[WithdrawalPool.sol] updateWithdrawalBatchIdCutoff() is used to update values withdrawalIdCutoff and withdrawalBatchIdCutoff . withdrawalBatchIdCutoff is used in getBatchIds and getFinalizedWithdrawalIdsByOwner view functions to more efficiently return data without iterating over all batches. By purposefully or by some innocent staker forgetting to call withdraw() on their queuedWithdrawal the updateWithdrawalBatchIdCutoff() will no longer update the withdrawalIdCutoff and withdrawalBatchIdCutoff because there will be a queuedWithdrawal with smaller index and still left with balance.
updateWithdrawalBatchIdCutoff() is used for updating withdrawalIdCutoff and withdrawalBatchIdCutoff to increase view function efficiency. It has a loop:
Because it depends on queuedWithdrawals, it is possible to permanently halt the optimization by simply not finalizing own withdrawal.
The only place that clears queuedWithdrawals balance is the withdraw() function:
But before that it has a check:
Because only the true owner can finalize and clear the balance once the malicious actor or forgetful staker successfully queues their withdrawal and not clears it, it will cause the optimization function to stop increasing the stored cutoff variables.
Updated existing hardhat test for withdrawals and checked withdrawalBatchIdCutoff and withdrawalIdCutoff values
The getBatchIds and getFinalizedWithdrawalIdsByOwner view functions will increasingly consume more and more computational resources to be called due to increasing iteration count. If the project uses 3rd party nodes this will cause the qoutas to increase and after longer periods of time can reach limits. If own node is used it will cause increasing computational pressure.
Manual review + hardhat test.
Few possible workarounds:
Allow WithdrawalPool owner to forcefully withdraw a queuedWithdrawal if it's been pending for a long time
Refactor getBatchIds to not iterate through all withdrawalBatches, but rather use some form of mapping get constant performance
Although this issue is somewhat mentioned in the LightChaser as "permanent Denial of Service (DoS) vulnerability", it is likely that the developers were hoping to solve it by using these stored cutoff variables. Which as described here are still open to circumvention.
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.