Omniscia Powercity Audit
TroveManager Manual Review Findings
TroveManager Manual Review Findings
TMR-01M: Incorrect Update of Aggregate Trackers in Recovery Mode
Type | Severity | Location |
---|---|---|
Logical Fault | TroveManager.sol:L602, L741 |
Description:
The TroveManager::_getTotalsFromLiquidateTrovesSequence_RecoveryMode
and TroveManager::_getTotalFromBatchLiquidate_RecoveryMode
functions will incorrectly update the system's aggregate collateral as the calculations will not factor in gas compensations nor surpluses.
Impact:
The system's recovery mode will assume that there is more collateral available to the system than in reality, causing it to improperly calculate incentives and thus aggravate the already-critical condition the system would be in recovery mode.
Example:
704function _getTotalFromBatchLiquidate_RecoveryMode705(706 IActivePool _activePool,707 IDefaultPool _defaultPool,708 uint _price,709 uint _LUSDInStabPool,710 address[] memory _troveArray711)712 internal713 returns(LiquidationTotals memory totals)714{715 LocalVariables_LiquidationSequence memory vars;716 LiquidationValues memory singleLiquidation;717
718 vars.remainingLUSDInStabPool = _LUSDInStabPool;719 vars.backToNormalMode = false;720 vars.entireSystemDebt = getEntireSystemDebt();721 vars.entireSystemColl = getEntireSystemColl();722
723 for (vars.i = 0; vars.i < _troveArray.length; vars.i++) {724 vars.user = _troveArray[vars.i];725 // Skip non-active troves726 if (Troves[vars.user].status != Status.active) { continue; }727 vars.ICR = getCurrentICR(vars.user, _price);728
729 if (!vars.backToNormalMode) {730
731 // Skip this trove if ICR is greater than MCR and Stability Pool is empty732 if (vars.ICR >= MCR && vars.remainingLUSDInStabPool == 0) { continue; }733
734 uint TCR = LiquityMath._computeCR(vars.entireSystemColl, vars.entireSystemDebt, _price);735
736 singleLiquidation = _liquidateRecoveryMode(_activePool, _defaultPool, vars.user, vars.ICR, vars.remainingLUSDInStabPool, TCR, _price);737
738 // Update aggregate trackers739 vars.remainingLUSDInStabPool = vars.remainingLUSDInStabPool.sub(singleLiquidation.debtToOffset);740 vars.entireSystemDebt = vars.entireSystemDebt.sub(singleLiquidation.debtToOffset);741 vars.entireSystemColl = vars.entireSystemColl.sub(singleLiquidation.collToSendToSP);742
743 // Add liquidation values to their respective running totals744 totals = _addLiquidationValuesToTotals(totals, singleLiquidation);745
746 vars.backToNormalMode = !_checkPotentialRecoveryMode(vars.entireSystemColl, vars.entireSystemDebt, _price);747 }748
749 else if (vars.backToNormalMode && vars.ICR < MCR) {750 singleLiquidation = _liquidateNormalMode(_activePool, _defaultPool, vars.user, vars.remainingLUSDInStabPool);751 vars.remainingLUSDInStabPool = vars.remainingLUSDInStabPool.sub(singleLiquidation.debtToOffset);752
753 // Add liquidation values to their respective running totals754 totals = _addLiquidationValuesToTotals(totals, singleLiquidation);755
756 } else continue; // In Normal Mode skip troves with ICR >= MCR757 }758}
Recommendation:
We advise them to be reverted to their original Liquity implementation as these adjustments can significantly affect the system's recovery mechanism, depicting it as having more collateral than actually available.
Alleviation (8bedd3b0df6387957e6b8f5d52507e776c1458b0):
The subtractions performed during recovery mode within the TroveManager
have been corrected per the updated Liquity implementation and using the GHSA-xh2p-7p87-fhgh advisory as a guideline.
As such, we consider this exhibit properly alleviated.