@@ -533,7 +533,7 @@ contract DelegationManager is
533533 * @dev This function completes a queued withdrawal for a staker.
534534 * This will apply any slashing that has occurred since the the withdrawal was queued by multiplying the withdrawal's
535535 * 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.
537537 * If receiveAsTokens is true, then these shares will be withdrawn as tokens.
538538 * If receiveAsTokens is false, then they will be redeposited according to the current operator the staker is delegated to,
539539 * and added back to the operator's delegatedShares.
@@ -550,16 +550,18 @@ contract DelegationManager is
550550
551551 uint256 [] memory prevSlashingFactors;
552552 {
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 ());
555557
556558 // Given the max magnitudes of the operator the staker was originally delegated to, calculate
557559 // the slashing factors for each of the withdrawal's strategies.
558560 prevSlashingFactors = _getSlashingFactorsAtBlock ({
559561 staker: withdrawal.staker,
560562 operator: withdrawal.delegatedTo,
561563 strategies: withdrawal.strategies,
562- blockNumber: completableBlock
564+ blockNumber: slashableUntil
563565 });
564566 }
565567
@@ -761,9 +763,12 @@ contract DelegationManager is
761763 ) internal view returns (uint256 ) {
762764 // Fetch the cumulative scaled shares sitting in the withdrawal queue both now and before
763765 // 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.
764769 uint256 curCumulativeScaledShares = _cumulativeScaledSharesHistory[operator][strategy].latest ();
765770 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
767772 });
768773
769774 // The difference between these values represents the number of scaled shares that entered the
@@ -937,7 +942,24 @@ contract DelegationManager is
937942 withdrawals[i] = queuedWithdrawals[withdrawalRoots[i]];
938943 shares[i] = new uint256 [](withdrawals[i].strategies.length );
939944
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+ }
941963
942964 for (uint256 j; j < withdrawals[i].strategies.length ; ++ j) {
943965 shares[i][j] = SlashingLib.scaleForCompleteWithdrawal ({
0 commit comments