Core Contracts

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

NFTs Stuck in Stability Pool Without Transfer or Managing Mechanism

Summary

When a liquidation is finalized in the Stability Pool, all of the user’s NFTs are transferred to the Stability Pool. However, there is no function in StabilityPool.sol to manage or transfer these NFTs, leading to a permanent lock of assets. Additionally, external contracts like Treasury.sol or an auction contract cannot retrieve or liquidate these NFTs, rendering them inaccessible without governance intervention.

Vulnerability Details

Lack of NFT Management in Stability Pool

When finalizeLiquidation() is executed, the liquidated user’s NFTs are transferred to the Stability Pool.

LendingPool.sol#L513-L519

// Transfer NFTs to Stability Pool
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;

However, StabilityPool does not provide any function to transfer or sell NFTs, meaning they cannot be accessed, used, or liquidated.

External Contracts Cannot Retrieve NFTs

Even if another contract (e.g., Treasury.sol) is designed to manage liquidated assets, it cannot retrieve NFTs from StabilityPool. This is because ERC-721 tokens require explicit approval (setApprovalForAll()) or direct transfers initiated by the contract holding them.

Since StabilityPool lacks a transfer function, these NFTs remain permanently locked in the contract.

Governance or Smart Contract Upgrade is Required for Recovery

Without an immediate fix, retrieving the locked NFTs would require a protocol upgrade via a governance proposal or a manual intervention from the deployer (if upgradeable via proxy).

This creates an unacceptable UX failure and can significantly harm the protocol.

Impact

  • Permanently Locked NFTs: Users who are liquidated will have their NFTs transferred to StabilityPool, but those NFTs will be stuck indefinitely since there is no function to access/transfer them.

  • Funds & Assets Cannot Be Recovered: Even if the protocol wants to auction or repurpose these NFTs, there is no way to interact with them.

  • Governance Dependency for Recovery: The only way to fix this issue is through a governance proposal or smart contract upgrade, which is slow, inconvenient, and potentially unfeasible in urgent cases.

Tools Used

Manual

Recommendations

Modify StabilityPool.sol to allow governance or an authorized entity to transfer NFTs out:

function transferNFT(address recipient, uint256 tokenId) external onlyOwnerOrGovernance {
nftContract.safeTransferFrom(address(this), recipient, tokenId);
}

This ensures that NFTs do not remain stuck and can be sent to another contract for proper handling.

Alternatively, modify finalizeLiquidation() so that liquidated NFTs are not sent to StabilityPool but directly to Treasury or a contract that can manage, liquidate, or redistribute them.

If StabilityPool is intended to sell or distribute these NFTs, implement an auction or liquidation function for this specific purpose too.

Updates

Lead Judging Commences

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

Liquidated RAACNFTs are sent to the StabilityPool by LendingPool::finalizeLiquidation where they get stuck

Support

FAQs

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