Core Contracts

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

Permanent NFT Lockup Due to Zero Debt Prevention in Liquidation

Summary

Users who have been flagged for liquidation and attempt to partially repay their debt can inadvertently lock their NFTs in the Lending contract forever. Apparently, if a user fully repays eventually before liquidation is finalized, their debt balance reaches zero, preventing StabilityPool.liquidateBorrower() from executing due to the if (userDebt == 0) revert InvalidAmount(); check. Since liquidation is never finalized, the Stability Pool cannot reclaim their NFTs, effectively locking them permanently in LendingPool.sol with no way to recover them.

Vulnerability Details

Users Can Reduce Their Debt to Zero Before Liquidation Finalization

liquidateBorrower() checks if userDebt == 0 and reverts if true.

StabilityPool.sol#L455

if (userDebt == 0) revert InvalidAmount();

If a user flagged for liquidation partially repays multiple times, they can reduce their debt to exactly zero before liquidation is finalized before/after the grace period has expired. The reasons can be several as I have reported separately, e.g. not calling closeLiquidation() in time after making a full repayment, being grieved for a large partial payment mistankenly made during liquidation and might as well pay the debt down to DoS the permissioned finalizeLiquidation(), etc. Consequently, the NFTs remain stuck forever in LendingPool.sol.

Lending Pool Contract Has No Mechanism to Release NFTs Manually

Once the liquidation process is triggered, users or the Stability Pool cannot withdraw their NFTs until the process is separately complete.

If liquidation never closes/finalizes, the NFTs remain trapped inside the Lending Pool contract indefinitely.

Neither the user nor the liquidator can retrieve them, leading to a deadlock scenario.

Impact

  • NFTs are permanently locked in the Lending Pool contract with no way to retrieve them.

  • Liquidation cannot be completed, breaking protocol functionality.

  • Users who try to repay their debt before liquidation finalization can suffer an irreversible loss of assets.

  • Liquidators miss out on arbitrage opportunity since they cannot claim seized collateral.

The only possible fix would require a governance intervention resorting to a smart contract upgrade via proxy, making this an unacceptable UX failure.

Tools Used

Manual

Recommendations

**Allow liquidateBorrower() to Execute Even If userDebt == 0 and lending.isUnderLiquidation[userAddress] = true

  • Instead of reverting, proceed with finalizing liquidation and releasing the NFTs if the debt is already cleared.

  • Return the NFTs to the user.

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.