The _repay function in the LendingPool contract calls the DebtToken.burn function to burn debt tokens and facilitate the repayment process. However, the burn function returns its values in an unexpected order. Instead of returning the scaled repayment amount as the first element, it returns the unscaled amount. Consequently, the repayment logic uses the unscaled value to transfer reserve assets, allowing borrowers to repay their loans without properly accounting for accrued interest.
Return Value Misinterpretation:
The _repay function includes the following code to burn debt tokens:
However, the DebtToken.burn function returns values in this order:
As a result, the variable amountScaled in _repay is actually assigned the unscaled repayment amount rather than the expected scaled value.
Incorrect Reserve Asset Transfer:
After burning the tokens, the _repay function transfers reserve assets using:
Since amountScaled is mistakenly the unscaled value, the transferred repayment amount does not include the proper accrued interest. This discrepancy enables users to repay only the principal, leaving the interest unpaid.
Unutilized Local Scaling Calculation:
Prior to the burn call, the function computes a local scaledAmount:
However, this computed value is not used anywhere in the repayment process, further compounding the issue.
Underpayment of Interest:
Borrowers can repay loans without covering the accrued interest, undermining the intended financial mechanics of the protocol.
Scenario Setup:
A borrower takes out a loan using NFT collateral.
Interest accrues over time, increasing the borrower's effective debt.
Repayment Attempt:
The borrower initiates a repayment transaction with a specified amount.
The _repay function calculates actualRepayAmount and then calls the DebtToken.burn function.
Return Value Misinterpretation:
The burn function returns a tuple where the first element is the unscaled amount (the principal) rather than the scaled amount (principal plus accrued interest).
The _repay function mistakenly uses this unscaled value for the transfer of reserve assets.
Outcome:
The borrower effectively repays only the principal without covering the accrued interest.
The debt remains overstated, and the protocol's accounting for interest accrual is compromised.
Manual review
Correct the Return Order in the Burn Function:
Modify the DebtToken.burn function so that it returns the scaled amount as the first element. For example:
This change will ensure that the _repay function correctly interprets the burned amount.
Adjust Repayment Logic in _repay:
Alternatively, update the _repay function in LendingPool to correctly handle the return order of the burn function. This could involve reordering the returned values after the burn call or applying additional scaling as necessary.
Utilize Computed Scaled Amount:
Ensure that the local calculation of scaledAmount is properly integrated into the repayment process to accurately represent the intended repayment value.
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.