Skip to content

Latest commit

 

History

History
63 lines (43 loc) · 2.78 KB

File metadata and controls

63 lines (43 loc) · 2.78 KB

Fast Khaki Raccoon

High

Liquidations will revert incorrectly due to an out-of-sync leftover collateral value

Summary

Liquidations will revert incorrectly due to an out-of-sync value

Root Cause

Upon liquidations, we have this code:

_leftoverCollateral = (_userCollateralBalance.toInt256() - _optimisticCollateralForLiquidator.toInt256());

_collateralForLiquidator = _leftoverCollateral <= 0 ? _userCollateralBalance : (_liquidationAmountInCollateralUnits * (LIQ_PRECISION + dirtyLiquidationFee)) / LIQ_PRECISION;

We compute an optimistic collateral for the liquidator which is based on cleanLiquidationFee. If the leftover collateral is not below 0, we recompute the collateral for liquidator based on the dirtyLiquidationFee which is a value lower than the clean fee (if we take a look at Fraxlend, it is 9000 vs 10000 for the clean fee).

Then, we have this code:

if (_leftoverCollateral <= 0) {
                ...
} else if (_leftoverCollateral < minCollateralRequiredOnDirtyLiquidation.toInt256()) {
       revert BadDirtyLiquidation();
}

If the leftover collateral is <=, we end up in the first block where we compute shares to adjust. If it is above 0 however, we will revert if we are under minCollateralRequiredOnDirtyLiquidation. The issue is that the leftover collateral is still based on the optimistic calculation which results in a much lower leftover collateral, resulting in reverts when the actual leftover collateral is not even close to minCollateralRequiredOnDirtyLiquidation.

Internal Pre-conditions

No response

External Pre-conditions

No response

Attack Path

  1. Let's imagine the following state:
  • userCollateralBalance = 2.3e18
  • dirtyLiquidationFee = 9_000 (based on Fraxlend)
  • cleanLiquidationFee = 10_000 (based on Fraxlend)
  • _liquidationAmountInCollateralUnits is equal to 2e18 based on the shares to liquidate provided by the user
  • minCollateralRequiredOnDirtyLiquidation is 1.1e17
  1. _optimisticCollateralForLiquidator will equal 2e18 * (1e5 + 1e4) / 1e5 = 2.2e18
  2. _leftoverCollateral equals 2.3e18 - 2.2e18 = 1e17
  3. As it is above 0, we recompute the collateral for liquidator which will equal 2e18 * (1e5 + 9e3) / 1e5 = 2.18e18
  4. As the leftover collateral is 1e17 and the minimum required collateral is 1.1e17, we will revert
  5. In reality, the actual leftover collateral is 2.3e18 - 2.18e18 = 1.2e17 as the collateral we will take out from the user is 2.18e18, not 2.2e18

Impact

Liquidations will revert incorrectly which is an extremely time-sensitive operation, this can lead to bad debt for the protocol

PoC

No response

Mitigation

Update the leftover collateral based on the new collateral for the liquidator