Core Contracts

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

Incorrect Curve Vault Integration Leads to Denial of Service of Deposits

Summary

The LendingPool::_depositIntoVault function attempts to deposit funds into Curve's vault from the wrong source contract, causing all deposits to fail when vault integration is enabled.

Vulnerability Details

The LendingPool contract incorrectly implements integration with Curve's vault in several ways:

1) In _depositIntoVault, it approves the vault to spend tokens from the LendingPool contract, but the actual funds are held in the RToken contract:

function _depositIntoVault(uint256 amount) internal {
// Incorrect: LendingPool doesn't hold the funds
@> IERC20(reserve.reserveAssetAddress).approve(address(curveVault), amount);
curveVault.deposit(amount, address(this));
totalVaultDeposits += amount;
}

2) The deposit call will fail because:

  • The funds are in RToken contract, not LendingPool, but the Curve vault transfers the funds from the msg.sender (ref)

  • The approval is given from the wrong contract

Proof of Concept

  1. User calls LendingPool::deposit(100) with 100 tokens

  2. Funds are transferred to RToken contract

  3. _rebalanceLiquidity() is called which tries to deposit excess into Curve vault

  4. _depositIntoVault() fails because:

    • LendingPool has no tokens to transfer

    • RToken hasn't approved LendingPool to spend its tokens

  5. The deposit transaction reverts, making deposits impossible when vault integration is enabled

Impact

  • Complete denial of service of the deposit functionality when Curve vault integration is enabled

  • Loss of yield generation capabilities since excess funds cannot be deposited into the vault

  • System cannot maintain proper liquidity buffer ratios

Recommendations

Option 1: Move funds to LendingPool first

Move the funds from the RToken contract to the LendingPool contract first, and then deposit into the Curve vault.

Option 2: Implement vault operations in RToken

Move all vault integration logic to the RToken contract since it holds the funds:

// In RToken.sol
function depositToVault(uint256 amount) external onlyReservePool {
IERC20(asset).approve(address(curveVault), amount);
curveVault.deposit(amount, address(this));
}
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

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

Support

FAQs

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