The PriorityPool::canWithdraw function is wrongly queried during upkeep processes in WithdrawalPool, leading to an overestimation of available funds in StakingPool, thus resulting in reverts due to insufficient liquidity.
The PriorityPool::canWithdraw function is intended to be called by users to determine how much an account can currently withdraw from the pool. However, during upkeep in the WithdrawalPool, the performUpkeep function calls PriorityPool::canWithdraw to determine how much can be withdrawn from the staking pool, resulting in an incorrect value.
To illustrate:
Assuming the following state for the WithdrawalPool when PriorityPool::canWithdraw is called:
totalQueued = 50
account queued = 0 (since the WithdrawalPool never makes deposits, this is always zero), thus canUnqueue = 0
WithdrawalPool balance = 400
StakingPool can withdraw = 100
Resulting withdrawable amount = 100 + 50 - 0 = 150
canWithdraw = 150
For clarity, let's assume that the current totalQueuedShareWithdrawals is greater than or equal to the computed canWithdraw value.
In WithdrawalPool::performUpkeep, this value is passed to PriorityPool::executeQueuedWithdrawals, which then attempts to withdraw 150 tokens from StakingPool. Since only 100 tokens are available, a revert occurs in StakingPool::withdraw, due to insufficient liquidity.
This will cause frequent reverts during the upkeep process, disrupting the withdrawal system.
Manual Review
Update WithdrawalPool::performUpkeep and checkUpkeep to query the StakingPool::canWithdraw function for the current withdrawable amount from the StakingPool instead.
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.