Omniscia Tren Finance Audit

TrenBoxManagerOperations Manual Review Findings

TrenBoxManagerOperations Manual Review Findings

TBO-01M: Improper Order of Operations

Description:

The TrenBoxManagerOperations::getRedemptionHints function will perform a subtraction of the gas compensation (i.e. an invocation of the TrenBase::_getNetDebt function) with the result of a Tren box's debt added to its pending reward.

This contradicts the original implementation, and permits a Tren box that has fallen below the minimum debt requirement to generate successful hints.

Impact:

Positions with a minimum debt less than the acceptable will generate proper redemption hints even though the redeem operation would eventually fail.

Example:

contracts/TrenBoxManagerOperations.sol
398uint256 currentTrenBoxNetDebt = _getNetDebt(
399 vars.asset,
400 ITrenBoxManager(trenBoxManager).getTrenBoxDebt(vars.asset, currentTrenBoxBorrower)
401 + ITrenBoxManager(trenBoxManager).getPendingDebtTokenReward(
402 vars.asset, currentTrenBoxBorrower
403 )
404);

Recommendation:

We advise the operations to be re-ordered, performing the addition after the net debt of the position has been calculated.

Alleviation (f6f1ad0b8f24a96ade345db1dd05a1878eb0f761):

All redemption related functionality of the protocol has been removed as an alleviation for TBO-03M, rendering this exhibit no longer applicable.

TBO-02M: Inexistent Assignment of Snapshots

Description:

The specialized TrenBoxManagerOperations::redistributeTrenBoxes function will not set the totalStakesSnapshot and totalCollateralSnapshot values that would normally be set via a call to the TrenBoxManager::updateSystemSnapshots_excludeCollRemainder which can cause significant misbehaviours in the way stakes are computed.

Impact:

The snapshots within the TrenBoxManager are not maintained properly as they are not assigned-to during an administrative TrenBoxManagerOperations::redistributeTrenBoxes call.

Example:

contracts/TrenBoxManagerOperations.sol
205function redistributeTrenBoxes(
206 address _asset,
207 uint256 _trenBoxes
208)
209 external
210 nonReentrant
211 onlyOwner
212{
213 LocalVariables_OuterLiquidationFunction memory vars;
214 LiquidationTotals memory totals;
215
216 vars.debtTokenInStabPool = IStabilityPool(stabilityPool).getTotalDebtTokenDeposits();
217 vars.price = IPriceFeed(priceFeed).fetchPrice(_asset);
218 vars.recoveryModeAtStart = _checkRecoveryMode(_asset, vars.price);
219
220 if (vars.recoveryModeAtStart) {
221 totals = _getTotalsFromLiquidateTrenBoxesSequence_RecoveryMode(
222 _asset, vars.price, vars.debtTokenInStabPool, _trenBoxes, true
223 );
224 } else {
225 totals = _getTotalsFromLiquidateTrenBoxesSequence_NormalMode(
226 _asset, vars.price, vars.debtTokenInStabPool, _trenBoxes, true
227 );
228 }
229
230 if (totals.totalDebtInSequence == 0) {
231 revert TrenBoxManagerOperations__NothingToLiquidate();
232 }
233
234 ITrenBoxManager(trenBoxManager).redistributeDebtAndColl(
235 _asset,
236 totals.totalDebtToRedistribute,
237 totals.totalCollToRedistribute,
238 totals.totalDebtToOffset,
239 0
240 );
241
242 emit Redistribution(
243 _asset,
244 totals.totalDebtInSequence,
245 totals.totalCollInSequence - totals.totalCollToClaim,
246 totals.totalDebtTokenGasCompensation
247 );
248}

Recommendation:

We advise the redistribution of Tren boxes via administrative action to be followed by a re-configuration of the snapshots with a _collRemainder of 0, ensuring the snapshots within the TrenBoxManager are maintained correctly.

Alleviation (f6f1ad0b8f24a96ade345db1dd05a1878eb0f761):

An invocation of the TrenBoxManager::updateSystemSnapshots_excludeCollRemainder function has been introduced to the TrenBoxManagerOperations::redistributeTrenBoxes function, alleviating this exhibit in full.

TBO-03M: Negative Dynamic Redemption Softening System

Description:

The redemption softening system will impose a "penalty" on the amount redeemed from a particular Tren box when performing redemptions which causes a consistent de-valuation of the debt token as the softening is applied solely to the collateral redeemed rather than being applied to the debt reduction as well.

Impact:

We consider the present negative market dynamics to weaken the purchasing power of the Tren system's debt token perpetually.

Example:

contracts/TrenBoxManagerOperations.sol
1183// Get the debtToken lot of equivalent value in USD
1184singleRedemption.collLot = (singleRedemption.debtLot * DECIMAL_PRECISION) / _price;
1185
1186// Apply redemption softening
1187singleRedemption.collLot =
1188 (singleRedemption.collLot * redemptionSofteningParam) / PERCENTAGE_PRECISION;

Recommendation:

We advise the system to be revised as it introduces a negative market dynamic that will result in a consistent devaluation of the debt token that can ultimately prove irrecoverable.

The mechanism in and of itself is difficult to introduce without significantly affecting the market dynamics of the Liquity-like protocol, and we advise this feature to be omitted.

Alleviation (f6f1ad0b8f24a96ade345db1dd05a1878eb0f761):

The Tren Finance team evaluated this exhibit and following month-long internal discussions have opted to remove the redemption system from the Tren Finance protocol entirely.

They believe that a de-peg event should be corrected via buyback and burn programs instead so as not to alienate users from the protocol due to redemptions resulting in a "bank-run" of collateral providers.

As the redemption system is no longer set in place, we consider this exhibit to be indirectly alleviated as a negative market dynamic no longer exists.