In withdrawalPool, when queued withdrawals receive deposited tokens to be finalized, the _finalizeWithdrawals function handles finalizing these withdrawals partialy or completely.
When there are not enough shares to satisy a queued withdrawal completely, it is partially finalized and then a batch is created for all the finalized withdrawals before it.
The issue arises when the leftover partially finalized withdrawal on the next call to _finalizeWthdrawals, if the withdrawal with the shares amount sent to finalize the withdrawal is still not enough to completely finalize it, it would create a duplicate of the previous batch(i.e having the same indexOfLastWithdrawal) but may have varying stakePerShare depending on the stake per share rate when the call is made.
This is the functionality here in the _finalizeWithdrawals in the WithdrawalPool contract, with some of my comments in the code...
If you take a look at the function closely you can see that when the withdrawal cannot be completely finalized it creates a batch for the previously fully finalized withdrawals.
The issue arises when the previously partially finalized queued withdrawal still cannot be fully finalized in subsequent calls.
E.g withdrawal id's 1 - 5 are batched together because withdrawal id 6 cannot be fully finalized with the available sharesToWithdraw. So withdrawal Id 6 is partially finalized and a batch is created for withdrawal Id's 1 -5.
On the next call to finalize withdrawals if the sharesToWithdraw is still not enought to fully finalize the withdrawal id 6, we end up creating a duplicate withdrawal batch of batch 1-5, this time the new batch may have a different sharePerStake due to the when the _finallizeWithdrawals the share per stake migh have changed (higher or lower or same).
These duplicate batches with different stake per shares would continue to be created so far the partially finalized withdrawal Id cannot be finalized for batching with the sharesToWithdrawused.
Keep track of the value of indexOfLastWithdrawalof the new batch to be created and if it matches the previous batch indexOfLastWithdrawal then dont create the batch, only finalize the partial withdrawal id.
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.