The _repay function in the LendingPool contract incorrectly calculates the user's debt by double-scaling the debt value. The balanceOf function in the DebtToken contract already returns a scaled debt value, but the _repay function further scales it by dividing by the usageIndex. This results in an incorrect debt calculation, leading to improper repayment amounts and potential financial discrepancies in the protocol.
The _repay function calls IDebtToken(reserve.reserveDebtTokenAddress).balanceOf(onBehalfOf) to retrieve the user's debt.
The balanceOf function in the DebtToken contract already scales the debt by multiplying the user's scaled balance by the usageIndex:
This means the returned value is already scaled.
In the _repay function, the scaled debt is incorrectly divided by the usageIndex again:
This results in an incorrect userScaledDebt value, leading to improper repayment calculations, the actualRepayAmount and scaledAmount are derived from the incorrectly scaled debt, causing further inaccuracies in the repayment logic.
Example
User's scaled balance: 100 tokens
Current usageIndex: 1.1e27 (10% interest)
User's debt (balanceOf): 100 * 1.1 = 110 tokens (already scaled)
Repayment Call:
User calls repay(110) to repay their debt.
Incorrect Calculation:
userDebt is retrieved as 110 tokens (already scaled).
userScaledDebt is calculated as 110 / 1.1 = 100 tokens (incorrectly scaled again).
actualRepayAmount is capped at 100 tokens instead of 110 tokens.
Result:
The user repays only 100 tokens instead of the full 110 tokens, leaving 10 tokens of residual debt.
Users may underpay their debt, leaving residual balances that should have been cleared.
Manual Review
Remove the redundant scaling in the _repay function. The userDebt value returned by balanceOf is already scaled and should not be divided by the usageIndex again.
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.