The issue occurs because the StabilityPool approves crvUSD for liquidation based on an outdated user debt value obtained before updating the LendingPool state. When the state is subsequently updated, the user's debt increases, causing the approved amount to be insufficient. This mismatch leads to a failed transfer during liquidation, ultimately reverting the process and potentially leaving undercollateralized positions unresolved.
Within the StabilityPool liquidation process, the user debt is first obtained from the LendingPool and then used to approve the LendingPool to withdraw crvUSD for liquidation. However, the LendingPool state—which contains updated indices reflecting accrued interest—is updated after this approval. As a consequence, the approved amount is based on stale data and is lower than the debt calculated after the state update.
Initial Debt Calculation in StabilityPool
The StabilityPool calls an internal update (_update()) and then retrieves the user’s debt from the LendingPool:
Approving crvUSD for Liquidation
after retrieving the debt, the contract approves the LendingPool to pull exactly userDebt scaled in crvUSD:
At this point, the approved amount is based on the pre-update state of the LendingPool with outdated usageIndex.
Updating the LendingPool State
The StabilityPool then calls lendingPool.updateState(), which updates the reserve state and refreshes indices (e.g., the usage index) to include newly accrued interest:
After this update, the actual user debt increases (for example, from 150 to 170 crvUSD) due to accruing interest.
Finalizing Liquidation in LendingPool
In the LendingPool’s finalizeLiquidation function, the updated user debt is used to burn debt tokens and transfer funds for liquidation:
Because the state update raises the user debt above the previously approved amount, the safeTransferFrom call fails due to insufficient allowance.
A mismatch between approved and actual debt leads to failed liquidations, blocking the process in critical situations.
Outdated approvals may accumulate, creating systemic liquidity issues in the protocol.
The reversion of liquidations due to insufficient funds can leave the system exposed to risk from non-liquidated, undercollateralized positions.
Foundry
Manual Review
To address this issue, the LendingPool state should be updated before approving crvUSD for liquidation. This could be achieved by reordering the operations in the StabilityPool's liquidation process, for example:
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.