Skip to content

Latest commit

 

History

History
95 lines (62 loc) · 2.68 KB

102.md

File metadata and controls

95 lines (62 loc) · 2.68 KB

Lucky Punch Ferret

Medium

rounding when calculating debtneeded causes loss for the protocol

Summary

DebtNeeded rounds down the calculation when collateral to liquidate exceeds user's balance.

When calculating the debt, if the collateral to liquidate exceeds the user's balance, the liquidator receives the total collateral balance of the borrower. The debt amount the liquidator will repay is recalculated, but the calculation rounds down the debt repayment amount. This is problematic because after the liquidation, the full collateral will be liquidated while leaving some debt due to the rounding. This remaining debt is directly added to the reserve deficit, causing the protocol to take the loss since it's added to the deficit.

When collateral exceeds user balance:

if (vars.maxCollateralToLiquidate > userCollateralBalance) {
  vars.collateralAmount = userCollateralBalance;
  vars.debtAmountNeeded = ((vars.collateralAssetPrice * vars.collateralAmount * debtAssetUnit) /
    (debtAssetPrice * collateralAssetUnit)).percentDiv(liquidationBonus);

The rounding down in this calculation means: Liquidator pays slightly less debt Gets full collateral amount Difference becomes bad debt Added to reserve deficit This directly conflicts with protocol goals: Avoiding dust/bad debt buildup Preventing loss of funds caused by liquidations

Root Cause

https://github.com/sherlock-audit/2025-01-aave-v3-3/blob/8da00c84076db02af24bfe20cc6b99e6738f743f/aave-v3-origin/src/contracts/protocol/libraries/logic/LiquidationLogic.sol#L650-L653

Internal Pre-conditions

collateral exceeds borrowers balance

External Pre-conditions

No response

Attack Path

No response

Impact

Each liquidation could create small amounts of bad debt Accumulates over time Protocol bears the loss

PoC

User has 1 ETH collateral ETH price: $2000 USDC price: $1 Liquidation bonus: 110%

debtAmountNeeded = ((2000e8 * 1e18 * 1e6) / (1e8 * 1e18)).percentDiv(11000)

  1. 2000e8 * 1e18 = 2000e26
    • 1e6 = 2000e32
  2. / 1e8 = 2000e24
  3. / 1e18 = 2000e6
  4. percentDiv(2000e6, 11000): (2000e6 * 10000) / 11000 = 1818.181818...e6 Rounds down to 1818e6 USDC

Result:

Liquidator pays: 1,818 USDC Gets: 1 ETH worth 2,000 USD Protocol loss: 0.181818... USDC per liquidation

Impact at scale: 100 such liquidations = 18.18 USDC loss 1000 liquidations = 181.81 USDC loss

loss per liquidation for the protocol

Expected repayment = 1818.181818... USDC Actual repayment = 1818.000000 USDC Loss = 0.181818... USDC

Loss percentage calculation: (0.181818... / 1818.181818...) * 100 = 0.0001 * 100 = 0.01% this makes this issue valid according to sherlock rules

Mitigation

round up when calculating the debtamount