Core Contracts

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

All NFTs are transferred in liquidation regardless of remaining debt

Summary

The finalizeLiquidation function in the LendingPool contract transfers all of a user's NFT collateral to the Stability Pool during liquidation, regardless of the user's remaining debt amount and the value of the NFTs. This can result in users losing significantly more collateral value than their outstanding debt.

Vulnerability Details

When a user's position is liquidated through finalizeLiquidation, the function transfers all NFTs to the Stability Pool without considering:

  1. The user's remaining debt amount after potential partial repayments during the grace period

  2. The individual value of each NFT

  3. The total collateral value versus remaining debt

function finalizeLiquidation(address userAddress) external nonReentrant onlyStabilityPool {
// ...
UserData storage user = userData[userAddress];
uint256 userDebt = user.scaledDebtBalance.rayMul(reserve.usageIndex);
// Transfers ALL NFTs regardless of their value or remaining debt
for (uint256 i = 0; i < user.nftTokenIds.length; i++) {
uint256 tokenId = user.nftTokenIds[i];
user.depositedNFTs[tokenId] = false;
raacNFT.transferFrom(address(this), stabilityPool, tokenId);
}
delete user.nftTokenIds;

A user who partially repays their debt during the grace period still loses all their NFTs, even if some NFTs are worth significantly more than the remaining debt.

Impact

High. Users can lose substantially more value in collateral than their outstanding debt amount. This creates unfair liquidation outcomes and could lead to:

Users losing high-value NFTs unnecessarily
Economic losses far exceeding the protocol's risk
Reduced user trust and participation in the protocol

Tools Used

Manual Review

Recommendations

Calculate the remaining debt after any grace period repayments

Updates

Lead Judging Commences

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

LendingPool::finalizeLiquidation() never checks if debt is still unhealthy

Support

FAQs

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

Give us feedback!