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:
Checking available liquidity via _ensureLiquidity.
If liquidity is insufficient, withdrawing the shortfall from the Curve Vault using _withdrawFromVault.
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.
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:
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
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.