In LendingPool.sol, once a borrower has had initiateLiquidation()called on their address, they can repay their debt within the grace period to avoid being liquidated. However, if borrower had repaid their debt but did not call closeLiquidation() in time, they will still get liquidated.
In closeLiquidation(), the function checks if the block.timestampis within the start time + grace period. If it is beyond that, revert.
Assume this scenario:
liquidationStartTime[Alice's address] = 1708423200
liquidationStartTime[Alice's address] + liquidationGracePeriod = 1708682400
Alice repays her debt fully at 1708681800
Alice only calls closeLiquidation()at 1708682401, which is beyond 1708682400
closeLiquidation()will revert
Now, Stability Pool can finalize the liquidation via finalizeLiquidation().Focusing on the snippet of the function below:
Since Alice had repaid her debt, assume that userDebt = 0.
Even when Alice does not have any more debt, all of her NFTs are still being transferred to Stability Pool
finalizeLiquidation()function does not check for Alice's actual debt. Alice will lose her collateral even when she has no debt.
There is no check to ensure that user indeed has remaining debt before liquidating. This leads to unfair losses for borrowers. For example, if a borrower's debt is much smaller than their total NFT value, borrowers will lose all of their NFTs.
Manual
In closeLiquidation(), store and check the timestamp of last repayment within the grace period, instead of checking against the current block.timestamp.
In finalizeLiquidation(), additional logic can be added to only liquidate based on the amount of remaining debt, instead of liquidating all of the borrower's NFTs.
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.