Core Contracts

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

No fallback mechanism for Curve vault withdrawal failures can block critical protocol functions

Relevant GitHub Links

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/pools/LendingPool/LendingPool.sol#L764-L765

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/pools/LendingPool/LendingPool.sol#L809-L811

Summary

LendingPool lacks fallback mechanisms for handling Curve vault withdrawal failures, which can block withdrawals, borrowing and potentially liquidations if the vault has insufficient liquidity.

Vulnerability Details

The _ensureLiquidity function attempts to withdraw from Curve vault when local liquidity is insufficient, but has no fallback if withdrawal fails due to insufficient vault liquidity. This causes the entire transaction to revert, blocking critical protocol functions.

function _ensureLiquidity(uint256 amount) internal {
if (address(curveVault) == address(0)) {
return;
}
uint256 availableLiquidity = IERC20(reserve.reserveAssetAddress).balanceOf(reserve.reserveRTokenAddress);
if (availableLiquidity < amount) {
uint256 requiredAmount = amount - availableLiquidity;
_withdrawFromVault(requiredAmount); // Will revert if not enough funds
}
}
function _withdrawFromVault(uint256 amount) internal {
curveVault.withdraw(amount, address(this), msg.sender, 0, new address[](0));
totalVaultDeposits -= amount;
}

Impact

If Curve vault has insufficient liquidity:

  • Users cannot withdraw their deposits

  • Borrowers cannot take new loans

  • Liquidations could be impacted

  • Protocol functionality is disrupted

  • Users lose access to funds temporarily

  • Potential loss of unmatured yield if system needs emergency pause

Proof of Concept

  1. Users deposit funds, excess is moved to Curve vault

  2. When user tries to withdraw:

  • If local liquidity insufficient, tries Curve withdrawal (of needed rest)

  • Withdrawal reverts due to insufficient vault funds (if needed rest is higher than available funds there)

  • User's withdrawal fails completely

  1. Protocol functions requiring liquidity are blocked

Tools Used

Manual review

Recommended Mitigation Steps

  1. Implement fallback mechanism for failed Curve withdrawals:

function _ensureLiquidity(uint256 amount) internal {
if (address(curveVault) == address(0)) {
return;
}
uint256 availableLiquidity = IERC20(reserve.reserveAssetAddress).balanceOf(reserve.reserveRTokenAddress);
if (availableLiquidity < amount) {
uint256 requiredAmount = amount - availableLiquidity;
try _withdrawFromVault(requiredAmount) {
// Withdrawal successful
} catch {
// Fallback: Allow partial withdrawal or trigger emergency procedures
emit CurveWithdrawalFailed(requiredAmount);
_handleCurveWithdrawalFailure();
}
}
}
  1. Add partial withdrawal support if full amount unavailable

  2. Implement proactive rebalancing based on liquidity thresholds

Updates

Lead Judging Commences

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

LendingPool core operations revert if Curve vault is unavailable during rebalancing, even when sufficient liquidity exists in the pool

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

LendingPool core operations revert if Curve vault is unavailable during rebalancing, even when sufficient liquidity exists in the pool

Support

FAQs

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

Give us feedback!