Core Contracts

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

Incorrect Curve Vault withdrawal parameters lead to locked funds and DoS

Summary

The LendingPool::_withdrawFromVault() function passes incorrect parameters to Curve's vault withdrawal function, which will cause withdrawals to fail and lock user funds in the vault.

Vulnerability Details

The _withdrawFromVault function is called during withdrawals and liquidity rebalancing to pull funds from the Curve vault. However, it passes incorrect parameters:

  1. The recipient is set to address(this) (LendingPool) instead of the RToken contract which holds all protocol funds

  2. The share owner is set to msg.sender instead of the LendingPool which owns the vault shares

function _withdrawFromVault(uint256 amount) internal {
// Incorrect parameters
curveVault.withdraw(
amount,
address(this), // Should be rToken address
msg.sender, // Should be address(this)
0,
new address[](0)
);
totalVaultDeposits -= amount;
}

The Curve vault expects (ref):

  • recipient: The address to receive the assets.

  • owner: The address who's shares are being burnt.

Since the LendingPool deposits into the vault (receiving shares) but tries to withdraw with msg.sender as the share owner, the withdrawal will revert.

Proof of Concept

  1. User deposits 100 tokens via LendingPool::deposit

  2. Tokens are sent to RToken contract

  3. During rebalancing, LendingPool deposits excess into Curve vault and receives shares

  4. Later when a user tries to withdraw:

    • _withdrawFromVault is called to pull funds from vault

    • Function passes msg.sender (user) as share owner instead of LendingPool

    • Vault reverts since user doesn't own any shares

    • Withdrawal fails and user funds remain locked

Impact

  • All withdrawals will fail when Curve vault integration is enabled due to incorrect withdrawal parameters

  • User funds deposited into the vault will be locked since they cannot be withdrawn

Recommendations

Fix withdrawal parameters:

function _withdrawFromVault(uint256 amount) internal {
curveVault.withdraw(
amount,
- address(this),
+ reserve.reserveRTokenAddress,
- msg.sender,
+ address(this),
0,
new address[](0)
);
totalVaultDeposits -= amount;
}
Updates

Lead Judging Commences

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

LendingPool::_depositIntoVault and _withdrawFromVault don't transfer tokens between RToken and LendingPool, breaking Curve vault interactions

LendingPool::_withdrawFromVault incorrectly uses msg.sender instead of address(this) as the owner parameter, causing vault withdrawals to fail

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

LendingPool::_depositIntoVault and _withdrawFromVault don't transfer tokens between RToken and LendingPool, breaking Curve vault interactions

LendingPool::_withdrawFromVault incorrectly uses msg.sender instead of address(this) as the owner parameter, causing vault withdrawals to fail

Support

FAQs

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