Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: medium
Valid

`LendingPool::finalizeLiquidation` even after user has cleared his debt because no invoked `LendingPool::closeLiquidation`

Summary

The LendingPool does not automatically close a user’s liquidation state after the user repays their debt. As a result, even if a user clears their debt (i.e. the debt falls below the DUST_THRESHOLD), the liquidation remains active because the contract requires a manual call to LendingPool::closeLiquidation(). This creates a risk that users may inadvertently remain under liquidation and face unexpected consequences even after clearing their debt.
In the LendingPool contract, the function used to close liquidation is defined as follows:

Vulnerability Details

In the LendingPool contract, the function used to close liquidation is defined as follows:

function closeLiquidation() external nonReentrant whenNotPaused {
address userAddress = msg.sender;
if (!isUnderLiquidation[userAddress]) revert NotUnderLiquidation();
// update state
ReserveLibrary.updateReserveState(reserve, rateData);
if (block.timestamp > liquidationStartTime[userAddress] + liquidationGracePeriod) {
revert GracePeriodExpired();
}
UserData storage user = userData[userAddress];
uint256 userDebt = user.scaledDebtBalance.rayMul(reserve.usageIndex);
if (userDebt > DUST_THRESHOLD) revert DebtNotZero();
isUnderLiquidation[userAddress] = false;
liquidationStartTime[userAddress] = 0;
emit LiquidationClosed(userAddress);
}

The problem is that even after a user has repaid enough debt so that their debt (user.scaledDebtBalance) is below the DUST_THRESHOLD, their liquidation state is not updated automatically. They must manually call closeLiquidation() to end the liquidation state. This dependency on manual intervention can lead to cases where users inadvertently remain under liquidation, hampering their ability to fully utilize the protocol even after clearing their debt.

Impact

  • User Experience Degradation: Users may be unaware of the need to manually close liquidation, leading to confusion and potential penalties or restricted functionality.

  • Operational Risk: Remaining under liquidation despite full repayment can adversely affect the user’s positions and interaction with the protocol.

  • Potential Exploitation: An attacker might exploit this behavior by delaying the closure, possibly affecting collateral management or delaying recovery of user privileges.

Tools Used

  • Manual Code Review

  • Unit Testing (as demonstrated by tests in LendingPool.test.js)

Recommendations

After processing a repayment, check if the user is under liquidation and if their scaled debt balance is below the DUST_THRESHOLD and if they are automate the close liquidation process.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

A borrower can LendingPool::repay to avoid liquidation but might not be able to call LendingPool::closeLiquidation successfully due to grace period check, loses both funds and collateral

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.