Liquid Staking

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

strategyWithdraw overrides getMintDeposits

Summary

The strategyWithdraw function allows the contract owner to withdraw funds from a strategy without respecting the minimum deposit requirements defined by getMinDeposits.
This can lead to the strategies' balances falling below their required minimums.

Vulnerability Details

The getMinDeposits function calculates the minimum amount of tokens that must remain in the pool across all strategies. It aggregates the minimum deposit requirements from each strategy to ensure that certain operational thresholds are maintained;

Contract: StakingPool.sol
217: function getMinDeposits() public view returns (uint256) {
218: uint256 min;
219:
220: for (uint256 i = 0; i < strategies.length; i++) {
221: IStrategy strategy = IStrategy(strategies[i]);
222: min += strategy.getMinDeposits();
223: }
224:
225: return min;
226: }

Each strategy implements its own getMinDeposits function, which may change dynamically based on the strategy's state.

Contract: VaultControllerStrategy.sol
591: function getMinDeposits() public view virtual override returns (uint256) {
592: return
593: fundFlowController.claimPeriodActive() ? totalDeposits - totalUnbonded : totalDeposits;
594: }

The strategyWithdraw function allows the contract owner to withdraw any amount from any strategy without enforcing the minimum deposit limit.

This action can reduce a strategy's balance below its minimum required deposits, which could lead to operational issues such as inability to meet min staking limits, increased risk due to insufficient liquidity, causing fewer rewards due to negative depositChange for the said strategy.

Contract: StakingPool.sol
182: /**
183: * @notice Manually withdraws asset tokens from a strategy
184: * @param _index index of strategy
185: * @param _amount amount to withdraw
186: * @param _data withdrawal data passed to strategy
187: **/
188: function strategyWithdraw(
189: uint256 _index,
190: uint256 _amount,
191: bytes calldata _data
192: ) external onlyOwner {
193: require(_index < strategies.length, "Strategy does not exist");
194: IStrategy(strategies[_index]).withdraw(_amount, _data);
195: }

Impact

Violating minimum requirements for staking, causing fewer rewards to the users in the concerned strategy

Tools Used

Manual Review

Recommendations

Modify strategyWithdraw to check that the withdrawal does not reduce the strategy's balance below its minimum required deposits.

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.