Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: medium
Invalid

The strategy withdraw is not withdrawing full amount, can lead to funds loss

Summary

The _withdrawLiquidity function assumes that when a strategy reports it can withdraw a certain amount, it will always successfully withdraw the full amount requested. This assumption is not verified, potentially leading to discrepancies between expected and actual withdrawn amounts.

Vulnerability Details

The vulnerability lies in the _withdrawLiquidity function:

function _withdrawLiquidity(uint256 _amount, bytes[] calldata _data) private {
uint256 toWithdraw = _amount;
for (uint256 i = strategies.length; i > 0; i--) {
IStrategy strategy = IStrategy(strategies[i - 1]);
uint256 strategyCanWithdrawdraw = strategy.canWithdraw();
if (strategyCanWithdrawdraw >= toWithdraw) {
strategy.withdraw(toWithdraw, _data[i - 1]); // @audit it doesn't withdraw all amount
break;
} else if (strategyCanWithdrawdraw > 0) {
strategy.withdraw(strategyCanWithdrawdraw, _data[i - 1]);
toWithdraw -= strategyCanWithdrawdraw;
}
}
}

The function breaks the withdrawal loop after calling strategy.withdraw, assuming full amount withdrawal. However, there's no verification that the full amount was actually withdrawn. This assumption is not true because the strategy withdraw doesn't check if full amount is withdrawn; it just send the amount back to staking pool.

Impact

The impact of this vulnerability could be severe:

  1. Accounting Discrepancies: The contract's internal accounting may become inaccurate, as it assumes full withdrawal when it might not have occurred.

  2. User Fund Loss: Users might receive less funds than they requested or are entitled to, leading to direct financial loss.

  3. Contract Insolvency: Over time, this could lead to a situation where the contract believes it has more funds than it actually does, potentially leading to insolvency.

  4. Trust Loss: Repeated discrepancies between requested and actual withdrawals could lead to a loss of user trust in the platform.

Where the Issue is Occurring and Likelihood

The issue occurs in the _withdrawLiquidity function, which is called by the withdraw function in the Staking Pool contract. This function is likely to be called frequently as it's a core part of the withdrawal process.

Likelihood: High

The likelihood of this issue manifesting is high because:

  1. It's in a critical path of the contract's functionality (withdrawals).

  2. The assumption of full withdrawal is made for every strategy that reports sufficient funds, multiplying the chances of occurrence.

Recommendations

  1. Verify Actual Withdrawal:

    uint256 actualWithdrawn = strategy.withdraw(toWithdraw, _data[i - 1]);
    toWithdraw -= actualWithdrawn;
    if (toWithdraw == 0) break;
  2. Update Loop Logic: Continue the loop if the full amount wasn't withdrawn, attempting to withdraw from the next strategy.

By implementing these recommendations, the contract can significantly reduce the risk associated with this vulnerability and improve the overall reliability of the withdrawal process.

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Appeal created

0xtheblackpanther Submitter
about 1 year ago
inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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