When WithdrawalPool::performUpkeep
calls priorityPool::canWithdraw
, it mistakenly passes address(WithdrawalPool)
as the account to check for queued tokens. Since the WithdrawalPool
contract itself is not a depositor and never has queued tokens, this results in the function reading zero queued tokens. Consequently, the condition for withdrawing is never met, causing performUpkeep
to revert every time.
In the WithdrawalPool::performUpkeep
function, the _account
parameter passed to priorityPool::canWithdraw
is set to address(this)
—the address of the WithdrawalPool
contract. This is problematic because WithdrawalPool
is not an external user and does not queue deposits, unlike regular depositors. As a result, when getQueuedTokens()
is called on the PriorityPool
, the accountQueuedTokens
mapping is accessed for the WithdrawalPool
contract's address, which always returns zero, since the WithdrawalPool
contract never interacts with the mapping to queue tokens.
This erroneous interaction occurs in the following code snippet:
This issue disrupts a core functionality of the protocol. The inability of performUpkeep
to proceed due to the perpetual reversion effectively breaks the withdrawal process. Since this function plays a critical role in maintaining the flow of withdrawals, the protocol cannot operate as intended without this bug being fixed.
Manual
Use a correct approach to get the total amount of tokens available in the deposit queue. Consider introducing a dedicated function for that.
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.