The LendingPool::_repay function in the protocol allows users to repay their outstanding debt. However, due to the way repayment amounts are handled, users may overpay without receiving a refund, leading to fund loss and misaccounting in the protocol. The issue arises because the function transfers amountScaled, which may be greater than the actual debt burned (amountBurned). Over time, this can result in significant user losses and inaccurate reserve balances. A proper fix involves ensuring that only the exact `amountBurned` is transferred and refunding any excess repayment to the user.
_repay FunctionCopyEdit
// Transfer reserve assets from the caller (msg.sender) to the reserve IERC20(reserve.reserveAssetAddress).safeTransferFrom(msg.sender, reserve.reserveRTokenAddress, amountScaled); // @audit-issue overpayment without refund
The function burns the user's debt tokens based on amountBurned, but transfers amountScaled, which may be greater than the actual required repayment.
There is no refund mechanism, meaning any excess payment is permanently lost.
User intends to repay their full debt.
The function calculates the amount to burn (amountBurned), which may be slightly less than the scaled debt (amountScaled).
More tokens are transferred (amountScaled), but the extra amount is not burned or refunded.
The user overpays, losing excess funds permanently.
Let’s assume the following:
userDebt = 1,000 tokens
usageIndex = 1.25
amount = 1,000 tokens (User intends to repay the full debt)
Expected Debt Repayment Calculation:
userScaledDebt=10001.25=800 tokens\text{userScaledDebt} = \frac{1000}{1.25} = 800 \text{ tokens}userScaledDebt=1.251000=800 tokensactualRepayAmount=min(1000,800)=800 tokens\text{actualRepayAmount} = \min(1000, 800) = 800 \text{ tokens}actualRepayAmount=min(1000,800)=800 tokensscaledAmount=8001.25=640 tokens\text{scaledAmount} = \frac{800}{1.25} = 640 \text{ tokens}scaledAmount=1.25800=640 tokens
🔹 Potential Overpayment:
If amountBurned = 800 tokens, but amountScaled = 640 tokens, then the function might transfer 640 tokens instead of burning 800, leading to inconsistencies.
If instead amountScaled is higher than amountBurned, then the user loses the difference, permanently overpaying without a refund.
User Overpayment:
If thousands of users repay their loans, small rounding errors accumulate, leading to massive fund losses over time.
Liquidity Distortion:
The reserve may hold excess funds due to overpayments, creating inconsistencies in available liquidity versus reported debt.
Protocol Accounting Errors:
Since overpaid amounts are not burned, the debt-to-reserve ratio becomes inaccurate, leading to unexpected liquidity constraints or incorrect interest rate calculations.
implement overpayment refunds
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.