Core Contracts

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

Withdrawal DoS: liquid crvUSD deposits locked in NFT Loans

Summary

The LendingPool protocol has a fundamental design flaw in its core mechanism: it takes liquid crvUSD deposits from users (promising instant liquidity via RTokens) and uses these funds to back illiquid NFT-collateralized loans. This creates an inherent mismatch between the liquidity promise made to depositors and the protocol's actual ability to fulfill withdrawals, regardless of the health of borrowing positions.

Vulnerability Details

The core issue lies in the protocol's basic mechanism:

// LendingPool.sol
function deposit(uint256 amount) external nonReentrant whenNotPaused onlyValidAmount(amount) {
// Users deposit liquid crvUSD
IERC20(reserve.reserveAssetAddress).safeTransferFrom(msg.sender, reserve.reserveRTokenAddress, amount);
// ReserveLibrary mint RTokens
IRToken(reserve.reserveRTokenAddress).mint(msg.sender, amount);
}

But then uses these liquid assets to back illiquid loans(NFTs):

function borrow(uint256 amount) external nonReentrant whenNotPaused onlyValidAmount(amount) {
// Accept illiquid NFT as collateral
UserData storage user = userData[msg.sender];
uint256 collateralValue = getUserCollateralValue(msg.sender);
// Give out liquid crvUSD against illiquid collateral
if (collateralValue > userTotalDebt.percentMul(liquidationThreshold)) {
IERC20(reserve.reserveAssetAddress).safeTransfer(msg.sender, amount);
}
}

When withdrawals are requested, the protocol can't fulfill them because the liquid assets are tied up in illiquid loans:

function withdraw(uint256 amount) external nonReentrant whenNotPaused onlyValidAmount(amount) {
// Try to fulfill withdrawal, but funds are in illiquid loans
_ensureLiquidity(amount); // Can only access vault, not borrowed funds
// This may fail due to insufficient liquidity
ReserveLibrary.withdraw(reserve, rateData, amount, msg.sender);
}

The _ensureLiquidity function cannot prevent withdrawal failures because it relies on withdrawing crvUSD from the curveVault, which contains the same crvUSD tokens that users deposited into the LendingPool. Even if all funds are withdrawn from the curveVault, there may still be insufficient tokens to process user withdrawals.

The issue becomes clear in this scenario:

  1. Users deposit 1000 crvUSD (liquid asset)

  2. Protocol lends out 900 crvUSD against NFTs (converting liquid → illiquid)

  3. Now pool only has 100 crvUSD.

  4. When depositors want their liquid assets back, the protocol can't deliver because:

    • The assets are tied up in illiquid loans

    • The collateral (NFTs) can't be converted to crvUSD

    • There's no mechanism to force loan termination

Impact

  • RToken holders cannot withdraw their deposits despite having the right to do so, as the majority of funds are borrowed out.

  • If borrowers remain in healthy positions, this situation could persist indefinitely with no resolution mechanism.

Tools Used

Manual Review

Recommendations

The protocol needs to restructure how it works with NFTs and lending of crvUSD tokens.

One solution is: the protocol covers instantly borrowed funds with its own treasury. This way the LendingPool would remain collateralized for RTokens holders.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

LendingPool faces withdrawal DoS risk due to liquidity mismatch between instantly redeemable RTokens and illiquid NFT-collateralized loans

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

LendingPool faces withdrawal DoS risk due to liquidity mismatch between instantly redeemable RTokens and illiquid NFT-collateralized loans

Support

FAQs

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