Core Contracts

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

Incorrect Asset Withdrawal Destination

Summary

An issue was identified in the LendingPool contract's withdraw function, specifically in the _ensureLiquidity(amount) logic. When a user attempts to withdraw an amount that exceeds reserve.reserveAssetAddress liquidity, the function attempts to withdraw from the vault to balance reserve.reserveAssetAddress. However, due to a misdirected transfer, the withdrawn funds are sent to address(this) (the LendingPool contract itself) instead of reserve.reserveAssetAddress. This leads to liquidity mismanagement, failed withdrawals, and potential fund loss

Vulnerability Details

  • The withdrawal operation is designed to fetch additional liquidity from the curveVault when the reserve.reserveAssetAddress has insufficient liquidity.

  • However, _withdrawFromVault(amount) mistakenly directs the withdrawn funds to address(this), instead of reserve.reserveAssetAddress, causing a liquidity shortfall in the reserve.

  • This results in a situation where the lending pool assumes it has sufficient liquidity for user withdrawals, but in reality, the assets remain locked in address(this).

  • 1. Call the `withdraw` function in the `LendingPool` contract with an amount greater than the available liquidity in the reserve.
    2. The `_ensureLiquidity` function will detect insufficient liquidity and call `_withdrawFromVault` to withdraw the required amount from the Curve vault.
    3. The `_withdrawFromVault` function will withdraw the funds and send them to `address(this)` instead of `reserve.reserveAssetAddress`.
    4. The withdrawn funds will be held by the `LendingPool` contract and will not be added to the reserve's liquidity pool.

Impact

The incorrect withdrawal destination can have this consequences:

  1. Liquidity Mismanagement: The lending pool assumes assets are available in reserve.reserveAssetAddress, but they are instead sent to address(this), leading to insufficient liquidity for withdrawals.

  2. User Withdrawals May Fail: If users attempt to withdraw funds, the contract may revert due to a lack of available liquidity.

  3. Funds May Become Stuck: If no mechanism exists to transfer funds from address(this) to reserve.reserveAssetAddress, assets could remain locked in the contract, requiring an admin intervention to fix.

  4. Accounting Inconsistencies: The protocol may incorrectly track available liquidity, potentially affecting calculations related to interest rates and reserve balances.

Tools Used

Recommendations

Modify _withdrawFromVault to ensure funds are correctly sent to reserve.reserveAssetAddress:

function _withdrawFromVault(uint256 amount) internal {
curveVault.withdraw(amount, reserve.reserveAssetAddress, msg.sender, 0, new address );
totalVaultDeposits -= amount;
}

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 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 7 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.

Give us feedback!