Liquid Staking

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

Potential array length mismatch in `_withdrawLiquidity` function could DoS the withdraw functionality

Summary

In the StakingPool contract, the internal _withdrawLiquidity() function withdraws liquidity from strategies by iterating over the strategies array in descending order. The function assumes that the provided _data array (containing withdrawal data for each strategy) is of the same length as the strategies array. However, there is no check to ensure this, which introduces a potential risk of an out-of-bounds error and contract reversion. This could lead to a denial of service (DoS) vulnerability during the withdrawal process, preventing users from withdrawing liquidity.

Vulnerability Details

The vulnerability lies in the following snippet of 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 strategyCanWithdraw = strategy.canWithdraw();
if (strategyCanWithdraw >= toWithdraw) {
@> strategy.withdraw(toWithdraw, _data[i - 1]); // @audit risk of out-of-bounds access
break;
} else if (strategyCanWithdraw > 0) {
@> strategy.withdraw(strategyCanWithdraw, _data[i - 1]); // @audit risk of out-of-bounds access
toWithdraw -= strategyCanWithdraw;
}
}
}

In this loop, the function assumes that the strategies array and _data array are the same length, and it directly accesses _data[i - 1] without verifying the lengths of these arrays. If _data is shorter than strategies, the access will result in an out-of-bounds array access, causing the transaction to revert.

Impact

Denial of Service (DoS): If the _data array is shorter than the strategies array, the contract will revert during the withdrawal process, causing a denial of service for users attempting to withdraw their liquidity. This can halt the normal operation of withdrawals within the protocol.

Tools Used

Manual code review

Recommendations

  1. Check for Array Length Consistency: Before proceeding with the withdrawal logic, ensure that the lengths of the strategies array and _data array are equal. This can be done by adding a require() statement at the beginning of the _withdrawLiquidity() function:

require(strategies.length == _data.length, "StakingPool: strategy and data length mismatch");
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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