In the finalizeLiquidation function, when liquidating a borrower's position, the debt amount is incorrectly transferred due to improper scaling during the burn process. The function calculates the total debt using rayMul on the user's scaledDebtBalance with the usageIndex. However, when passed to the burn function, the value is adjusted to match the user's debt token balance rather than their actual borrowed amount, leading to an incomplete liquidation.
In finalizeLiquidation, the debt is determined using:
This userDebt amount is then passed to the burn function, but if the user's debt token balance is lower than this amount, the function limits the burn amount to the user's debt token balance and returns this reduced amount as amountScaled.
Back in the lending pool contract, the liquidation process relies on the returned amountScaled value instead of the actual userDebt, leading to an incorrect debt transfer:
The burn function does not always process the full user debt and caps it to the user's existing debt token balance instead of the total borrowed amount.
The finalizeLiquidation function then uses this reduced value (amountScaled) instead of the full userDebt, resulting in a partial liquidation rather than a full position closure.
A user borrows 1000 tokens but only has 500 debt tokens in their balance.
During liquidation, the contract attempts to burn 1000 tokens but only 500 are available, so the burn function caps the burn amount at 500 tokens.
As a result, amountScaled = 500, which is less than the actual borrowed debt (1000 tokens).
The lending pool then transfers only 500 tokens instead of the full 1000 tokens, leaving the liquidation incomplete.
Incomplete Liquidation:
The borrower still owes debt even after liquidation because only a portion of their debt is repaid.
The lending pool's accounting becomes inconsistent, which may lead to incorrect debt tracking and potential financial loss for the protocol.
Manual Code Review and Contract Behavior Analysis
To ensure complete liquidation, the finalizeLiquidation function should use userDebt instead of amountScaled when transferring funds from the stability pool:
Update the transfer function as follows:
By using userDebt instead of amountScaled, the contract will correctly pay off the full outstanding debt rather than a partial amount, ensuring complete liquidation and accurate debt tracking.
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.