Liquid Staking

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

The user cannot withdraw assets if the remaining amount, after partial filling the queue deposit, is below the minimum in the `queueWithdrawal` function.

Summary

The protocol allows immediate withdrawals and deposits in Stakelink staking, for efficient asset flow. This is achieved by transferring pending deposits to users withdrawing assets from Stakelink, and vice versa.

However, the issue arises when queuing a withdrawal. First, if the deposit queue is non-zero, the withdrawal amount is filled with the queue deposit. If some amount remains, the queueWithdrawal function is called. This function enforces a minWithdrawalAmount check, which prevents users from withdrawing their assets if the remaining amount is below the minimum threshold.

Vulnerability Details

To withdraw assets from pool, user will call PriorityPool:withdraw function. which will call internal _withdraw function

2024-09-stakelink/contracts/core/priorityPool/PriorityPool.sol:663
663: function _withdraw(
664: address _account,
665: uint256 _amount,
666: bool _shouldQueueWithdrawal
667: ) internal returns (uint256) {
668: if (poolStatus == PoolStatus.CLOSED) revert WithdrawalsDisabled();
669:
670: uint256 toWithdraw = _amount;
671:
672: if (totalQueued != 0) {
673: uint256 toWithdrawFromQueue = toWithdraw <= totalQueued ? toWithdraw : totalQueued;
674:
675: totalQueued -= toWithdrawFromQueue;
676: depositsSinceLastUpdate += toWithdrawFromQueue;
677: sharesSinceLastUpdate += stakingPool.getSharesByStake(toWithdrawFromQueue);
678: toWithdraw -= toWithdrawFromQueue;
679: }
680:
681: if (toWithdraw != 0) {
682: if (!_shouldQueueWithdrawal) revert InsufficientLiquidity();
683: withdrawalPool.queueWithdrawal(_account, toWithdraw); // @audit : due to min chek it will revert here and user will not be able to withdraw
684: }
685:

It can be observed from the code that the withdrawal amount will either be fully or partially filled. The issue arises when the amount is partially filled, _shouldQueueWithdrawal=true, and toWithdraw < minWithdrawalAmount.

2024-09-stakelink/contracts/core/priorityPool/WithdrawalPool.sol:304
304: function queueWithdrawal(address _account, uint256 _amount) external onlyPriorityPool {
305: if (_amount < minWithdrawalAmount) revert AmountTooSmall(); // @audit : it could revert due to filling the order at from assets in pr pool
306:

Impact

The user will not be able to withdraw assets from the pool, even if the initial withdrawal request meets the minimum required amount.

Tools Used

Manual Review

Recommendations

Add a check inside the _withdraw function to ensure that the amount queued for withdrawal is not less than the required minimum if the amount is partially filled from queued deposits.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

A withdrawal of totalQueued + x with x < minWithdrawal amount will revert

Support

FAQs

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