In PriorityPool.sol, when withdrawing, if _shouldUnqueue is true, accountQueuedTokens can be used for the withdrawal.
However, accountQueuedTokens cannot be used if they are greater than totalQueued.
When accountQueuedTokens change, totalQueued must change as well.
PriorityPool.sol
However, in _withdraw and _depositQueuedTokens, totalQueued decreases but accountQueuedTokens do not change.
Over time, the cumulative total of accountQueuedTokens becomes greater than totalQueued, resulting in some users being completely unable to use their accountQueuedTokens.
In other words, tokens deposited for accountQueuedTokens can become permanently locked, which essentially means a loss of user funds.
When totalStakeAmount reaches its limit, no further staking occurs and the tokens are placed in a queue based on user choice.
If users who have no funds in the queue proceed to withdraw, totalQueued decreases first.
During this, there is no change in the funds of individual users who are waiting.
If a user with funds in the queue attempts to withdraw or call the unqueueTokens function to retrieve their queued funds, they cannot retrieve more than the totalQueued.
- withdraw function
This means that if the sum of individual users' accountQueuedTokens exceeds totalQueued, there is no way to reduce this discrepancy, leading to a permanent freezing of user funds.
Thus, even without deliberate attacks, the system's own operations can lead to the freezing of user funds.
If an attacker carries out a sandwich attack, this damage can be further accelerated and increased.
In this POC, the process is demonstrated where an attacker carries out a sandwich attack to accelerate and increase the damage
However, it is important to remember that even without a deliberate attack by an attacker, damage occurs once the totalStakedAmount reaches its limit.
add this code in priority-pool.test.ts
Over time, the difference between the total sum of accountQueuedTokens and totalQueued grows, and this difference ultimately means a permanent loss of user funds.
If an attacker carries out a sandwich attack, they can cause damage more quickly and more extensively.
The reduction of totalQueued in the _withdraw and _depositQueuedTokens functions is related to the amount of stakingPool tokens transferred into the PriorityPool contract.
This means that there are more stakingPool tokens in the PriorityPool than the difference between the total sum of accountQueuedTokens and totalQueued.
In other words, when calling the withdraw or unqueueTokens functions, if _amountToUnqueue is equal to or less than accountQueuedTokens[account] and greater than totalQueued, the stakingPool.withdraw function must be called to burn the stakingPool tokens within PriorityPool and obtain the necessary underlyingTokens for the amount of _amountToUnqueue - totalQueued.
When calling the unqueueTokens and withdraw functions, if the amountToUnqueue is greater than totalQueued, the necessary tokens can be obtained by calling the stakingPool.withdraw function to retrieve the needed tokens.
I also believe that there should be logic added to use the user's accountQueuedTokens for deposits. An additional function could be introduced for this purpose. Otherwise, instead of adding to the accountQueuedTokens during deposits, those tokens should be returned to the user.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.