H-1: Liquidated condition can easily be griefed via donations
Summary:
After the vault has been liquidated, the condition to have a null collateral amount can be broken via donations, potentially leading to bricked withdrawals.
Description:
Given liquidations in MonoCooler seize all the collateral, the implementation of _isVaultPositionLiquidated() checks if the position has zero collateral.
861: function _isVaultPositionLiquidated(uint256 totalDeposited) private view returns (bool) {
862: /* The condition `totalDeposited > 1` is used instead of `!= 0` because, in an extremely rare case,
863: * 1 token unit may remain on the strategy's balance after withdrawing all OHM deposits.
864: * When migrating to a debt token with lower decimals, the division rounds up to ensure
865: * the Callisto vault receives exactly enough tokens to cover its debt.
866: * See `DebtTokenMigrator.migrateDebtToken()` for details.
867: * Any remaining token unit after withdrawing all deposits is considered as an empty balance.
868: * The minimum debt requirement of Olympus Cooler Loans V2 should prevent passing this condition when
869: * not liquidated.
870: */
871: return totalDeposited > 1 && OLYMPUS_COOLER.accountCollateral(address(this)) == 0;
872: }
However, the MonoCooler can operate on behalf of other accounts. In particular, it allows donations via the addCollateral() functions.
A donation of just one wei would be enough to block emergency withdrawals, while regular withdrawals would also fail due to the insolvency of the vault.
Impact:
High. The issue can lead to a denial of service in the withdrawal logic, blocking exits from the vault.
Recommendation:
Given the difficulty in correctly assessing whether a position has been liquidated, and considering that this should be a rare event, it might be more reasonable to delegate the task to a trusted operator who can toggle the emergency status.
Developer Response:
We have added a state variable collateralGOHM that we modify each time the vault position in Cooler v2 is increased or decreased. Now we just compare this value with the actual collateral amount in Cooler v2. If value in Cooler v2 is less than collateralGOHM, we assume the position has been liquidated.
Fixed in commit 9704f43.