Core Contracts

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

Misdirection of Assets From the Curve Vault to the LendingPool

Summary

There is a critical issue in how liquidity is managed between the Curve Vault and the LendingPool contract. While user deposits increase the RToken balance, keeping liquidity available in many cases, the _rebalanceLiquidity() function is supposed to ensure an optimal liquidity distribution. However, it fails to do so because _withdrawFromVault() directs liquidity from the Curve Vault to the LendingPool contract instead of the RToken contract. This misrouting causes inconsistencies in liquidity management and can lead to withdrawal failures.

Vulnerability Details

TThe withdraw(uint256 amount) function in the LendingPool contract is designed to allow users to redeem their RTokens for reserve assets. It does this by first ensuring that enough liquidity is available using _ensureLiquidity(), processing the withdrawal, and then calling _rebalanceLiquidity() to adjust the liquidity distribution.

In a normal flow, deposits from users increase the balance of reserveRTokenAddress, making liquidity available for withdrawals. However, _rebalanceLiquidity() is responsible for maintaining an optimal liquidity ratio by moving excess liquidity to the Curve Vault or pulling liquidity from it when needed. The problem arises when _rebalanceLiquidity() attempts to withdraw funds from the Curve Vault and relies on _withdrawFromVault().

The _withdrawFromVault() function currently withdraws liquidity from the Curve Vault but mistakenly directs it to the LendingPool contract (address(this)) instead of the reserveRTokenAddress. This creates a serious issue because when users later attempt to withdraw their funds, the liquidity is expected to be in reserveRTokenAddress, but it is actually sitting in the LendingPool contract.

This issue does not immediately block all withdrawals because user deposits continuously replenish the reserve balance. However, when liquidity levels fluctuate, _rebalanceLiquidity() fails to properly balance the system, which can lead to liquidity shortages at reserveRTokenAddress and, in turn, failed withdrawals.

Impact

Because liquidity from the Curve Vault is being sent to the wrong address, _rebalanceLiquidity() is unable to maintain a proper liquidity balance situations where many users deposit, liquidity might remain available at reserveRTokenAddress simply because deposits keep it funded. However, in a scenario where withdrawals increase or there is a high demand for liquidity, the flaw in _rebalanceLiquidity() becomes evident. Users expecting to receive reserve assets may find that the contract cannot fulfill their withdrawal requests, even though the liquidity technically exists—it is just stuck in the wrong place.

Tools Used

Manual Review

Recommendations

The best way to resolve this issue is to modify _withdrawFromVault() so that when liquidity is pulled from the Curve Vault, it is correctly routed to reserveRTokenAddress. This ensures that when users burn their RTokens to withdraw reserve assets, the liquidity is actually available in the right location.

Updates

Lead Judging Commences

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