Omniscia Euler Finance Audit

Liquidation Manual Review Findings

Liquidation Manual Review Findings

LNO-01M: Improper Liquidation Incentive Calculations

Description:

The Liquidation::calculateMaxLiquidation mechanism will artificially create bad debt due to the discountFactor for low LTV configurations. Specifically, a liquidate-able position may be able to recover fully with the collateral available yet can be liquidated to force the discounted collateral-attached debt to be socialized.

As an example configuration using simplistic terms:

  • Asset LTV: 0.5
  • Asset Balance: 100 USD
  • Asset Liquidity Collateral Value: 50 USD
  • Asset Liquidity Liability Value: 100 USD

In the above example, the discountFactor will be maximized (i.e. 80%) and thus the maxYieldValue will exceed the available balance of the asset (i.e. 100 USD / 80% = 125 USD).

As a result, the ensuing if conditional will lower the maxRepayValue to 80 USD even though the position has sufficient collateral to fulfil its liability obligations.

Impact:

Under certain conditions, the liquidation incentives offered by the Liquidation::calculateMaxLiquidation function can be capitalized by liquidators to create bad debt by forcing a position into insolvency even though value-wise the position would be solvent.

Additionally, the present system effectively incentivizes users to liquidate their own collateral via a secondary account thus repaying their position at a discount.

Example:

src/EVault/modules/Liquidation.sol
112function calculateMaxLiquidation(LiquidationCache memory liqCache, VaultCache memory vaultCache)
113 private
114 view
115 returns (LiquidationCache memory)
116{
117 // Check account health
118
119 (uint256 liquidityCollateralValue, uint256 liquidityLiabilityValue) =
120 calculateLiquidity(vaultCache, liqCache.violator, liqCache.collaterals, LTVType.LIQUIDATION);
121
122 // no violation
123 if (liquidityCollateralValue > liquidityLiabilityValue) return liqCache;
124
125 // Compute discount
126
127 uint256 discountFactor = liquidityCollateralValue * 1e18 / liquidityLiabilityValue; // health score = 1 - discount
128
129 if (discountFactor < 1e18 - MAXIMUM_LIQUIDATION_DISCOUNT) {
130 discountFactor = 1e18 - MAXIMUM_LIQUIDATION_DISCOUNT;
131 }
132
133 // Compute maximum yield
134
135 uint256 collateralBalance = IERC20(liqCache.collateral).balanceOf(liqCache.violator);
136 uint256 collateralValue =
137 vaultCache.oracle.getQuote(collateralBalance, liqCache.collateral, vaultCache.unitOfAccount);
138
139 if (collateralValue == 0) {
140 // worthless collateral can be claimed with no repay
141 liqCache.yieldBalance = collateralBalance;
142 return liqCache;
143 }
144
145 uint256 liabilityValue = liqCache.owed.toUint();
146 if (address(vaultCache.asset) != vaultCache.unitOfAccount) {
147 // liquidation, in contrast to liquidity calculation, uses mid-point pricing instead of bid/ask
148 liabilityValue =
149 vaultCache.oracle.getQuote(liabilityValue, address(vaultCache.asset), vaultCache.unitOfAccount);
150 }
151
152 uint256 maxRepayValue = liabilityValue;
153 uint256 maxYieldValue = maxRepayValue * 1e18 / discountFactor;
154
155 // Limit yield to borrower's available collateral, and reduce repay if necessary
156 // This can happen when borrower has multiple collaterals and seizing all of this one won't bring the violator back to solvency
157
158 if (collateralValue < maxYieldValue) {
159 maxRepayValue = collateralValue * discountFactor / 1e18;
160 maxYieldValue = collateralValue;
161 }
162
163 liqCache.repay = (maxRepayValue * liqCache.owed.toUint() / liabilityValue).toAssets();
164 liqCache.yieldBalance = maxYieldValue * collateralBalance / collateralValue;
165
166 return liqCache;
167}

Recommendation:

We advise the discountFactor to solely be applied if the collateralValue exceeds the liabilityValue as otherwise toxic debt will be created at the expense of the system.

To note, the documentation line that precedes the referenced if conditional should be corrected as the conditional can trigger under the aforementioned conditions which do not fall under the "insolvency" category.

Alleviation (fb2dd77a6f):

The Euler Finance team evaluated this exhibit and has opted to acknowledge it as an inherent economical risk to lending protocols. Additionally, the Euler Finance team maintained that the proposed mitigation would cause toxic debt to be further exacerbated as no one would desire to liquidate it.

To clarify the exhibit's original intentions, the proposed mechanism is to offer a discount on excess collateralValue that exceeds the liabilityValue solely when that case is applicable. Specifically, we propose that a position that is able to be liquidated while recovering fully should offer a discount on the extra collateral the user holds.

Toxic liquidations (i.e. under-collateralized positions) should retain their present behaviour and impose a discount unconditionally, as at that point toxic debt is unavoidable. The exhibit's focus is toxic debt that is avoidable without an expense to the protocol, simply by reducing the incentive of the liquidator rather than eliminating it.

We invite the Euler Finance team to re-visit this exhibit, as well as adjust the documentation line outlined in the last sentence of the "Recommendation" chapter regardless of their action.

Alleviation (0f2192ac81):

We engaged in extensive discussions with the Euler Finance team debating the proposed liquidation incentive mechanism, the outputs of which have been reflected in the Dutch Liquidation Analysis authored by the Euler Finance team.

In summary, we consider the proposed mechanism sufficiently deliberated within the paper and we are aligned with all criticism levied; especially in relation to partial liquidations and their impact on the overall game-theory mechanics that surround liquidations.

As a result of these efforts, we consider this exhibit to be informational in nature and to be nullified as the original incentive model employed by the Euler Finance team does not lead to any active vulnerability and has been considered the optimal approach based on the business requirements of the Euler Finance team.