Liquid Staking

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

Lack of Withdrawal Pool Balance Check May Lead to Transaction Fai

Summary

The PriorityPool::executeQueuedWithdrawals function transfers tokens from the withdrawal pool to the priority pool but assumes that the withdrawal pool always has sufficient tokens to complete the transaction. There is no check in place to verify the balance of the withdrawal pool before initiating the transfer. This may result in failed transactions when the withdrawal pool does not hold enough tokens to cover the requested withdrawal amount.

Vulnerability Detail

In the PriorityPool::executeQueuedWithdrawals function, the contract transfers tokens from the WithdrawalPool to the priority pool via the safeTransferFrom method. However, the function does not check whether the WithdrawalPool has enough tokens to cover the requested withdrawal amount (_amount). If the WithdrawalPool has insufficient balance, the transaction will fail, leading to failure of all the batch of withdraw .

The function assumes that the WithdrawalPool always has sufficient funds to fulfill the withdrawal request, which may not always be true in real-world scenarios.

Impact

The absence of a balance check in the WithdrawalPool could lead to failed transaction of batch withdraw and potential denial of service for users attempting to withdraw tokens. This failure could degrade the user experience and create uncertainty regarding withdrawals. If not addressed, this issue could become a significant operational risk, especially during periods of high withdrawal activity.

Code Snippet

https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/priorityPool/PriorityPool.sol#L520

function executeQueuedWithdrawals(
uint256 _amount,
bytes[] calldata _data
) external onlyWithdrawalPool {
IERC20Upgradeable(address(stakingPool)).safeTransferFrom(
msg.sender,
address(this),
_amount
);
stakingPool.withdraw(address(this), address(this), _amount, _data);
token.safeTransfer(msg.sender, _amount);
}

Tool used

Manual Review

Recommendation

Before executing the withdrawal, add a check to verify that the withdrawal pool has sufficient tokens to fulfill the requested withdrawal amount. This can be done using a balance check such as:

function executeQueuedWithdrawals(
uint256 _amount,
bytes[] calldata _data
) external onlyWithdrawalPool {
+ require(token.balanceOf(address(this)) >= _amount, "Insufficient balance in withdrawal pool");
IERC20Upgradeable(address(stakingPool)).safeTransferFrom(
msg.sender,
address(this),
_amount
);
stakingPool.withdraw(address(this), address(this), _amount, _data);
token.safeTransfer(msg.sender, _amount);
}

This will ensure that the transaction only proceeds if the withdrawal pool has enough tokens, preventing failed transactions due to insufficient funds.

Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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