A critical ordering flaw exists in the liquidation process where interest rate updates occur after debt calculations. The StabilityPool.liquidateBorrower
function retrieves borrower debt using stale interest indices from LendingPool.getUserDebt
before updating state via LendingPool.updateState
. This mismatch between debt calculations and actual accrued interest allows liquidations to operate on outdated financial data, risking failed transactions and protocol insolvency during market volatility. The core issue violates fundamental interest accrual sequencing requirements in lending protocols.
The vulnerability arises from incorrect ordering of state updates and debt calculations in the liquidation process StabilityPool.liquidateBorrower
(StabilityPool.sol#L464). The root cause is that interest accrual updates are performed after retrieving the borrower's debt amount, leading to calculations based on stale interest rates.
Key problematic flow:
In StabilityPool.liquidateBorrower
:
Retrieves debt amount using lendingPool.getUserDebt()
before updating state
Calls lendingPool.updateState()
after debt calculation
LendingPool.getUserDebt
uses outdated reserve.usageIndex
ReserveLibrary.updateReserveInterests
updates critical interest indices that should precede debt queries
This creates a race condition where liquidations use interest rates from the previous accrual period rather than the current state. The miscalculation propagates through:
Incorrect scaledUserDebt
value used for balance checks
Improper CRVUSD approval amount for finalizing liquidation
The vulnerability violates the intended protocol logic where interest accrual should always precede any debt-related operations, as defined in the interest rate model implementation.
The incorrect interest accrual timing creates two critical failure modes:
Underestimated Debt Liquidation (Interest Rate Increase)
When outdated usage interest < actual interest:
Stability Pool balance check passes using stale lower debt value
LendingPool.finalizeLiquidation
computes debt with updated higher usageIndex
Transaction reverts due to insufficient funds during LendingPool interaction
Results in failed liquidations despite passing initial checks
Overestimated Debt Lockup (Interest Rate Decrease)
When outdated usage interest > actual interest:
Stability Pool balance check fails using stale higher debt value
Legitimate liquidations prevented despite sufficient actual funds
Protocol loses liquidation opportunities during favorable market conditions
The combination creates systemic risk where liquidations become unreliable precisely when needed most (during market volatility), undermining RAAC's core collateral management mechanism.
Manual Review
call LendingPool.updateState
to update usage index before calculating the user debt for liquidation check and preparation:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.