Liquid Staking

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

Inconsistent Token Withdrawal from Queue

Summary

User deposits flagged to be queued (using _shouldQueue) are not correctly processed after they enter the queue. Although the contract properly increases the global totalQueued variable and the user-specific accountQueuedTokens, these values are not correctly updated when the tokens are withdrawn. This can lead to permanently locked user funds and incorrect balance tracking.

Vulnerability Details

Description

  • When users deposit tokens and the _shouldQueue flag is set to true, the contract correctly increments both the global totalQueued and the user's individual balance in accountQueuedTokens[_account].

    accountQueuedTokens[_account] += toDeposit;
    totalQueued += toDeposit;
  • However, when these queued tokens are withdrawn, the contract only reduces the global totalQueued variable, while failing to reduce accountQueuedTokens[_account] accordingly. This results in a situation where the global queue is reduced, but individual user balances still reflect the old, higher amount.

  • This inconsistency leads to the possibility of users being unable to unqueue or access their queued tokens, as the system believes those tokens are still in the queue, even though they may have been processed.

Code Snippet

In the _deposit function:

if (_shouldQueue) {
_requireNotPaused();
if (accountIndexes[_account] == 0) {
accounts.push(_account);
accountIndexes[_account] = accounts.length - 1;
}
accountQueuedTokens[_account] += toDeposit;
totalQueued += toDeposit;
}

This part correctly increments both accountQueuedTokens[_account] and totalQueued.

in the _withdraw function:

if (totalQueued != 0) {
uint256 toWithdrawFromQueue = toWithdraw <= totalQueued ? toWithdraw : totalQueued;
totalQueued -= toWithdrawFromQueue;
depositsSinceLastUpdate += toWithdrawFromQueue;
sharesSinceLastUpdate += stakingPool.getSharesByStake(toWithdrawFromQueue);
toWithdraw -= toWithdrawFromQueue;
}

The contract only decreases totalQueued without adjusting the user’s accountQueuedTokens.

Problematic Behavior:

The user’s queued tokens remain locked and inaccessible because the accountQueuedTokens[_account] variable does not reflect the actual state after processing.

Impact

  • Locked User Funds: Users may experience permanently locked funds, as their individual balances (accountQueuedTokens[_account]) do not decrease even after their tokens are processed.

  • Unqueue Failure: Users trying to unqueue tokens may encounter failed transactions due to the mismatch between accountQueuedTokens[_account] and the actual state of the queue.

  • Incorrect Balance Reporting: The system will report incorrect user balances, which could disrupt other functionalities, such as withdrawals or future deposits.

Tools Used

Recommendations

Update User Balances: Ensure that accountQueuedTokens[_account] is reduced when the corresponding queued tokens are withdrawn. Example fix:

accountQueuedTokens[_account] -= toDepositFromQueue;
Updates

Lead Judging Commences

inallhonesty Lead Judge
9 months ago
inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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