Core Contracts

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

Incorrect Share Ownership in Vault Withdrawals Causes Core Functions to Revert

Relevant Context

The LendingPool contract interacts with a Curve vault to manage deposits. The vault operations are critical for core functionalities like deposits, withdrawals and borrowing, which all rely on the _rebalanceLiquidity() function that in turn calls _withdrawFromVault().

Finding Description

The _withdrawFromVault() function incorrectly passes msg.sender as the owner parameter when calling curveVault.withdraw(). However, the vault shares are owned by the LendingPool contract itself (address(this)), not by the user interacting with the pool.

This creates a mismatch between the actual owner of the shares (LendingPool) and the claimed owner (msg.sender) in the withdrawal call, which will cause the transaction to revert due to insufficient share balance and missing token approvals.

Since _withdrawFromVault() is called by _rebalanceLiquidity(), which is in turn used by core functions like deposit(), withdraw(), and borrow(), this issue affects these main functions when rebalancing is needed.

Impact Explanation

High. When triggered, the issue causes core contract functionality (deposits, withdrawals, borrowing) to be completely unusable as transactions will revert. This represents a complete failure of the contract's main purpose in scenarios requiring rebalancing.

Likelihood Explanation

Medium. This issue will manifest when currentBuffer < desiredBuffer, requiring the pool to withdraw funds from the vault to rebalance liquidity. While this is a common scenario in normal operations, it's not guaranteed to occur on every transaction.

Proof of Concept

  1. User calls deposit() function with some amount

  2. deposit() calls _rebalanceLiquidity()

  3. If currentBuffer < desiredBuffer, _rebalanceLiquidity() determines some amount needs to be withdrawn from the vault and calls _withdrawFromVault()

  4. _withdrawFromVault() attempts to withdraw using the user's address as owner

  5. The transaction reverts because:

    • The user doesn't own any vault shares (they are owned by the LendingPool)

    • The user hasn't approved the LendingPool to spend their vault shares (which they don't have anyway)

Recommendation

The owner parameter in the vault withdrawal should be set to address(this) since the LendingPool contract is the actual owner of the shares. Update the _withdrawFromVault() function as follows:

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

Lead Judging Commences

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

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

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

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.

Give us feedback!