Core Contracts

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

The withdrawal function may fail due to a rounding error

Summary

Potential vulnerability was identified in the withdraw function and its interaction with the _ensureLiquidity and _withdrawFromVault functions. The issue stems from the lack of precise handling of token amounts when withdrawing from the Curve Vault. Due to rounding discrepancies inherent in Curve’s share-to-amount conversion, the pool may end up with slightly less liquidity than required (e.g., off by 1 wei), causing the withdrawal to fail unexpectedly. This could disrupt user operations and potentially lead to a denial-of-service scenario for withdrawals.

Vulnerability Details

The withdraw function allows users to burn RTokens to withdraw reserve assets from the pool. The process involves:

  1. Checking available liquidity via _ensureLiquidity.

  2. If liquidity is insufficient, withdrawing the shortfall from the Curve Vault using _withdrawFromVault.

  3. Transferring the requested amount to the user.

The _ensureLiquidity function calculates the requiredAmount as the difference between the requested amount and the pool’s current availableLiquidity. However, the _withdrawFromVault function does not verify the exact amount of assets received from the Curve Vault. Since Curve Vault operates based on shares that are converted to underlying amounts, rounding errors can occur—first downward when converting the requested amount to shares, and then potentially upward or downward depending on Curve’s internal logic. This can result in a final amount transferred to the pool that differs slightly from the requiredAmount, potentially leaving the pool with insufficient funds to fulfill the withdrawal.

For example:

  • User requests 1000 wei.

  • Pool has 500 wei, so requiredAmount = 500 wei.

  • Curve Vault converts 500 wei to shares (e.g., 499 wei due to rounding), then converts shares back to 499 wei.

  • Pool ends up with 999 wei total, which is less than the 1000 wei needed.

This discrepancy, even if just 1 wei, causes the withdraw function to fail because the pool cannot meet the exact amount requested.

LendingPool.sol

VaultV3.vy

Impact

Failed Withdrawals: Users may be unable to withdraw their funds due to insufficient liquidity caused by rounding errors, even when the pool appears to have sufficient resources.

Tools Used

Manual code review

Recommendations

To mitigate this vulnerability, consider the following improvements:

  1. Introduce Slippage Tolerance:

    • Modify the withdraw function to accept a minAmountOut parameter, allowing users to specify the minimum amount they are willing to receive. This ensures the transaction succeeds even if the exact amount cannot be met due to rounding.

    • Example modification:

      solidity

      function withdraw(uint256 amount, uint256 minAmountOut) external nonReentrant whenNotPaused onlyValidAmount(amount) {
      if (withdrawalsPaused) revert WithdrawalsArePaused();
      ReserveLibrary.updateReserveState(reserve, rateData);
      _ensureLiquidity(amount);
      (uint256 amountWithdrawn,,) = ReserveLibrary.withdraw(reserve, rateData, amount, msg.sender);
      if (amountWithdrawn < minAmountOut) revert InsufficientAmountWithdrawn();
      _rebalanceLiquidity();
      emit Withdraw(msg.sender, amountWithdrawn);
      }
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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