Liquid Staking

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

Incorrect implementation of `PriorityPool::canWithdraw` allows withdrawals from the queue despite paused contract state

Summary

The function PriorityPool::canWithdraw incorrectly calculates withdrawal amounts when the contract is paused. Although canUnqueue is set to zero when the contract is paused to prevent users from unqueuing tokens, the logic still subtracts canUnqueue from totalQueued. This results in an inflated withdrawal limit because the totalQueued pool expands to offset the intended restriction of canUnqueue, effectively bypassing the pause condition. As a result, users can withdraw more tokens than intended, even when the contract is paused.

Vulnerability Details

The vulnerability stems from the calculation of stLINKCanWithdraw within PriorityPool::canWithdraw. When the contract is paused, the protocol correctly sets canUnqueue to zero to prevent users from unqueuing tokens:

uint256 canUnqueue = paused() ? 0 : MathUpgradeable.min(getQueuedTokens(_account, _distributionAmount), totalQueued);

However, in the next calculation, canUnqueue is subtracted from totalQueued, and this altered value is used to calculate stLINKCanWithdraw:

uint256 stLINKCanWithdraw = MathUpgradeable.min(
stakingPool.balanceOf(_account),
stakingPool.canWithdraw() + totalQueued - canUnqueue
);

When canUnqueue is zero, the subtraction from totalQueued artificially increases the effective withdrawal limit. This negates the intention of the paused() condition, as the very tokens that should be restricted from being unqueued are still indirectly available for withdrawal by being included in totalQueued.

You can view the relevant code here:

Impact

This issue compromises the protocol's ability to enforce the paused state during critical situations. By allowing withdrawals even when unqueuing is restricted, the protocol risks moving more tokens than it should, leading to potential security vulnerabilities. This flaw can disrupt the balance of queued tokens and affect the accuracy of off-chain systems that rely on the contract's state for updates, such as PriorityPool::updateDistribution. Since PriorityPool::canWithdraw is also used by WithdrawalPool::performUpkeep to determine how many tokens to move, bypassing the pause restrictions undermines the protocol's safeguards and stability mechanisms.

Tools Used

Manual

Updates

Lead Judging Commences

inallhonesty Lead Judge
11 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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