A vulnerability was discovered in the liquidateBorrower()
function that could prevent the liquidation of a borrower even when the pool holds sufficient funds to cover their debt. The issue stems from the incorrect calculation of scaledUserDebt
, which applies interest twice, resulting in an inflated debt value.
Affected Code: StabilityPool::liquidateBorrower
The issue occurs in the following line within the liquidateBorrower()
function:
getUserDebt()
already returns the user's actual debt with the interest, which is computed as:
Here, usageIndex
represents accumulated interest.
getNormalizedDebt()
returns the current usageIndex
.
Multiplying userDebt
by getNormalizedDebt()
applies interest twice:
The double interest calculation is happening in this line:
The issue arises because userDebt
already includes interest, and multiplying it by getNormalizedDebt()
applies the interest again.
1. User Borrowing:
The user borrows 10 units of crvUSD
.
At the time of borrowing:
reserve.usageIndex = 1e27
reserve.liquidityIndex = 1e27
Over time:
reserve.usageIndex
increases to 1.5e27
.
reserve.liquidityIndex
increases to 1.3e27
.
2. getUserDebt()
Calculation:
Formula: getUserDebt = scaledDebtBalance × current usageIndex
Compute scaledDebtBalance
:
scaledDebtBalance = borrowed amount ÷ usageIndex at borrow time
scaledDebtBalance = 10 ÷ 1e27 = 10e-27
Compute getUserDebt
:
getUserDebt = 10e-27 × 1.5e27 = 15
getUserDebt()
returns 15 units, reflecting accrued interest.
3. scaledUserDebt
Calculation (Double Interest Issue):
Formula (incorrect): scaledUserDebt = getUserDebt × liquidityIndex
Compute scaledUserDebt
:
scaledUserDebt = 15 × 1.3e27 = 19.5e27
Interest is applied twice, inflating the debt to 19.5 instead of the correct 15.
Failed Liquidation: The system will attempt to liquidate the borrower using an inflated debt amount (scaledUserDebt
), which could exceed the pool's actual balance.
Loss of Funds: Liquidation will revert with an InsufficientBalance
error, even if the pool has enough to cover the borrower's real debt.
Manual code review
Remove the calculation that scales user debt by more interest.
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.