@@ -533,7 +533,7 @@ contract DelegationManager is
533
533
* @dev This function completes a queued withdrawal for a staker.
534
534
* This will apply any slashing that has occurred since the the withdrawal was queued by multiplying the withdrawal's
535
535
* scaledShares by the operator's maxMagnitude for each strategy. This ensures that any slashing that has occurred
536
- * during the period the withdrawal was queued until its completable timestamp is applied to the withdrawal amount.
536
+ * during the period the withdrawal was queued until its slashableUntil block is applied to the withdrawal amount.
537
537
* If receiveAsTokens is true, then these shares will be withdrawn as tokens.
538
538
* If receiveAsTokens is false, then they will be redeposited according to the current operator the staker is delegated to,
539
539
* and added back to the operator's delegatedShares.
@@ -550,16 +550,18 @@ contract DelegationManager is
550
550
551
551
uint256 [] memory prevSlashingFactors;
552
552
{
553
- uint32 completableBlock = withdrawal.startBlock + MIN_WITHDRAWAL_DELAY_BLOCKS;
554
- require (completableBlock <= uint32 (block .number ), WithdrawalDelayNotElapsed ());
553
+ // slashableUntil is block inclusive so we need to check if the current block is strictly greater than the slashableUntil block
554
+ // meaning the withdrawal can be completed.
555
+ uint32 slashableUntil = withdrawal.startBlock + MIN_WITHDRAWAL_DELAY_BLOCKS;
556
+ require (slashableUntil < uint32 (block .number ), WithdrawalDelayNotElapsed ());
555
557
556
558
// Given the max magnitudes of the operator the staker was originally delegated to, calculate
557
559
// the slashing factors for each of the withdrawal's strategies.
558
560
prevSlashingFactors = _getSlashingFactorsAtBlock ({
559
561
staker: withdrawal.staker,
560
562
operator: withdrawal.delegatedTo,
561
563
strategies: withdrawal.strategies,
562
- blockNumber: completableBlock
564
+ blockNumber: slashableUntil
563
565
});
564
566
}
565
567
@@ -761,9 +763,12 @@ contract DelegationManager is
761
763
) internal view returns (uint256 ) {
762
764
// Fetch the cumulative scaled shares sitting in the withdrawal queue both now and before
763
765
// the withdrawal delay.
766
+ // NOTE: We want all the shares in the window [block.number - MIN_WITHDRAWAL_DELAY_BLOCKS, block.number]
767
+ // as this is all slashable and since prevCumulativeScaledShares is being subtracted from curCumulativeScaledShares
768
+ // we do a -1 on the block number to also include (block.number - MIN_WITHDRAWAL_DELAY_BLOCKS) as slashable.
764
769
uint256 curCumulativeScaledShares = _cumulativeScaledSharesHistory[operator][strategy].latest ();
765
770
uint256 prevCumulativeScaledShares = _cumulativeScaledSharesHistory[operator][strategy].upperLookup ({
766
- key: uint32 (block .number ) - MIN_WITHDRAWAL_DELAY_BLOCKS
771
+ key: uint32 (block .number ) - MIN_WITHDRAWAL_DELAY_BLOCKS - 1
767
772
});
768
773
769
774
// The difference between these values represents the number of scaled shares that entered the
@@ -937,7 +942,24 @@ contract DelegationManager is
937
942
withdrawals[i] = queuedWithdrawals[withdrawalRoots[i]];
938
943
shares[i] = new uint256 [](withdrawals[i].strategies.length );
939
944
940
- uint256 [] memory slashingFactors = _getSlashingFactors (staker, operator, withdrawals[i].strategies);
945
+ uint32 slashableUntil = withdrawals[i].startBlock + MIN_WITHDRAWAL_DELAY_BLOCKS;
946
+
947
+ uint256 [] memory slashingFactors;
948
+ // If slashableUntil block is in the past, read the slashing factors at that block
949
+ // Otherwise read the current slashing factors. Note that if the slashableUntil block is the current block
950
+ // or in the future then the slashing factors are still subject to change before the withdrawal is completable
951
+ // and the shares withdrawn to be less
952
+ if (slashableUntil < uint32 (block .number )) {
953
+ slashingFactors = _getSlashingFactorsAtBlock ({
954
+ staker: staker,
955
+ operator: operator,
956
+ strategies: withdrawals[i].strategies,
957
+ blockNumber: slashableUntil
958
+ });
959
+ } else {
960
+ slashingFactors =
961
+ _getSlashingFactors ({staker: staker, operator: operator, strategies: withdrawals[i].strategies});
962
+ }
941
963
942
964
for (uint256 j; j < withdrawals[i].strategies.length ; ++ j) {
943
965
shares[i][j] = SlashingLib.scaleForCompleteWithdrawal ({
0 commit comments