@@ -210,7 +210,8 @@ contract IntegrationCheckUtils is IntegrationBase {
210
210
User staker ,
211
211
User operator ,
212
212
IStrategy[] memory strategies ,
213
- uint [] memory shares ,
213
+ uint [] memory depositShares ,
214
+ uint [] memory withdrawableShares ,
214
215
Withdrawal[] memory withdrawals ,
215
216
bytes32 [] memory withdrawalRoots
216
217
) internal {
@@ -226,11 +227,11 @@ contract IntegrationCheckUtils is IntegrationBase {
226
227
"check_QueuedWithdrawal_State: calculated withdrawals should match returned roots " );
227
228
assert_Snap_Added_QueuedWithdrawals (staker, withdrawals,
228
229
"check_QueuedWithdrawal_State: staker should have increased nonce by withdrawals.length " );
229
- assert_Snap_Removed_OperatorShares (operator, strategies, shares ,
230
+ assert_Snap_Removed_OperatorShares (operator, strategies, withdrawableShares ,
230
231
"check_QueuedWithdrawal_State: failed to remove operator shares " );
231
- assert_Snap_Removed_Staker_DepositShares (staker, strategies, shares ,
232
+ assert_Snap_Removed_Staker_DepositShares (staker, strategies, depositShares ,
232
233
"check_QueuedWithdrawal_State: failed to remove staker shares " );
233
- assert_Snap_Removed_Staker_WithdrawableShares (staker, strategies, shares ,
234
+ assert_Snap_Removed_Staker_WithdrawableShares (staker, strategies, withdrawableShares ,
234
235
"check_QueuedWithdrawal_State: failed to remove staker withdrawable shares " );
235
236
}
236
237
@@ -248,6 +249,7 @@ contract IntegrationCheckUtils is IntegrationBase {
248
249
// ... check that the staker is undelegated, all strategies from which the staker is deposited are unqueued,
249
250
// that the returned root matches the hashes for each strategy and share amounts, and that the staker
250
251
// and operator have reduced shares
252
+ assert_HasNoDelegatableShares (staker, "staker should have withdrawn all shares " );
251
253
assertFalse (delegationManager.isDelegated (address (staker)),
252
254
"check_Undelegate_State: staker should not be delegated " );
253
255
assert_ValidWithdrawalHashes (withdrawals, withdrawalRoots,
@@ -268,7 +270,8 @@ contract IntegrationCheckUtils is IntegrationBase {
268
270
269
271
function check_Redelegate_State (
270
272
User staker ,
271
- User operator ,
273
+ User prevOperator ,
274
+ User newOperator ,
272
275
IDelegationManagerTypes.Withdrawal[] memory withdrawals ,
273
276
bytes32 [] memory withdrawalRoots ,
274
277
IStrategy[] memory strategies ,
@@ -282,13 +285,16 @@ contract IntegrationCheckUtils is IntegrationBase {
282
285
// and operator have reduced shares
283
286
assertTrue (delegationManager.isDelegated (address (staker)),
284
287
"check_Redelegate_State: staker should not be delegated " );
288
+ assertEq (address (newOperator), delegationManager.delegatedTo (address (staker)), "staker should be delegated to operator " );
289
+ assert_HasExpectedShares (staker, strategies, new uint [](strategies.length ), "staker should not have deposit shares after redelegation " );
290
+ assert_Snap_Unchanged_OperatorShares (newOperator, "new operator should not have received any shares " );
285
291
assert_ValidWithdrawalHashes (withdrawals, withdrawalRoots,
286
292
"check_Redelegate_State: calculated withdrawal should match returned root " );
287
293
assert_AllWithdrawalsPending (withdrawalRoots,
288
294
"check_Redelegate_State: stakers withdrawal should now be pending " );
289
295
assert_Snap_Added_QueuedWithdrawals (staker, withdrawals,
290
296
"check_Redelegate_State: staker should have increased nonce by withdrawals.length " );
291
- assert_Snap_Removed_OperatorShares (operator , strategies, stakerDelegatedShares,
297
+ assert_Snap_Removed_OperatorShares (prevOperator , strategies, stakerDelegatedShares,
292
298
"check_Redelegate_State: failed to remove operator shares " );
293
299
assert_Snap_Removed_Staker_DepositShares (staker, strategies, stakerDepositShares,
294
300
"check_Redelegate_State: failed to remove staker shares " );
@@ -349,7 +355,7 @@ contract IntegrationCheckUtils is IntegrationBase {
349
355
if (operator != staker) {
350
356
assert_Snap_Unchanged_TokenBalances (operator, "operator should not have any change in underlying token balances " );
351
357
}
352
- assert_Snap_Added_OperatorShares (operator, withdrawal. strategies, withdrawal.scaledShares , "operator should have received shares " );
358
+ assert_Snap_Added_OperatorShares (operator, strategies, shares , "operator should have received shares " );
353
359
}
354
360
}
355
361
@@ -438,7 +444,7 @@ contract IntegrationCheckUtils is IntegrationBase {
438
444
/// @dev Check global max magnitude invariants - these should ALWAYS hold
439
445
function check_MaxMag_Invariants (
440
446
User operator
441
- ) internal {
447
+ ) internal view {
442
448
assert_MaxMagsEqualMaxMagsAtCurrentBlock (operator, allStrats, "max magnitudes should equal upperlookup at current block " );
443
449
assert_MaxEqualsAllocatablePlusEncumbered (operator, "max magnitude should equal encumbered plus allocatable " );
444
450
}
@@ -447,7 +453,7 @@ contract IntegrationCheckUtils is IntegrationBase {
447
453
function check_ActiveModification_State (
448
454
User operator ,
449
455
AllocateParams memory params
450
- ) internal {
456
+ ) internal view {
451
457
OperatorSet memory operatorSet = params.operatorSet;
452
458
IStrategy[] memory strategies = params.strategies;
453
459
@@ -459,15 +465,15 @@ contract IntegrationCheckUtils is IntegrationBase {
459
465
User operator ,
460
466
OperatorSet memory operatorSet ,
461
467
IStrategy[] memory strategies
462
- ) internal {
468
+ ) internal view {
463
469
assert_IsSlashable (operator, operatorSet, "operator should be slashable for operator set " );
464
470
assert_CurMinSlashableEqualsMinAllocated (operator, operatorSet, strategies, "minimum slashable stake should equal allocated stake at current block " );
465
471
}
466
472
467
473
function check_NotSlashable_State (
468
474
User operator ,
469
475
OperatorSet memory operatorSet
470
- ) internal {
476
+ ) internal view {
471
477
assert_NotSlashable (operator, operatorSet, "operator should not be slashable for operator set " );
472
478
assert_NoSlashableStake (operator, operatorSet, "operator should not have any slashable stake " );
473
479
}
@@ -893,8 +899,8 @@ contract IntegrationCheckUtils is IntegrationBase {
893
899
check_IsSlashable_State (operator, operatorSet, allocateParams.strategies);
894
900
895
901
// Slashing SHOULD change max magnitude and current allocation
896
- assert_Snap_Slashed_MaxMagnitude (operator, slashParams, "slash should lower max magnitude " );
897
- assert_Snap_Slashed_EncumberedMagnitude (operator, slashParams, "slash should lower max magnitude " );
902
+ assert_Snap_Slashed_MaxMagnitude (operator, operatorSet, slashParams, "slash should lower max magnitude " );
903
+ assert_Snap_Slashed_EncumberedMagnitude (operator, slashParams, "slash should lower encumbered magnitude " );
898
904
assert_Snap_Slashed_AllocatedStake (operator, operatorSet, slashParams, "slash should lower allocated stake " );
899
905
assert_Snap_Slashed_SlashableStake (operator, operatorSet, slashParams, "slash should lower slashable stake " );
900
906
assert_Snap_Slashed_OperatorShares (operator, slashParams, "slash should remove operator shares " );
@@ -905,97 +911,19 @@ contract IntegrationCheckUtils is IntegrationBase {
905
911
assert_Snap_Unchanged_AllocatableMagnitude (operator, allStrats, "slashing should not change allocatable magnitude " );
906
912
assert_Snap_Unchanged_Registration (operator, operatorSet, "slash should not change registration status " );
907
913
assert_Snap_Unchanged_Slashability (operator, operatorSet, "slash should not change slashability status " );
908
- assert_Snap_Unchanged_AllocatedSets (operator, "should not have updated allocated sets " );
909
- assert_Snap_Unchanged_AllocatedStrats (operator, operatorSet, "should not have updated allocated strategies " );
914
+ // assert_Snap_Unchanged_AllocatedSets(operator, "should not have updated allocated sets");
915
+ // assert_Snap_Unchanged_AllocatedStrats(operator, operatorSet, "should not have updated allocated strategies");
910
916
}
911
917
912
- // TODO: improvement needed
913
-
914
- function check_Withdrawal_AsTokens_State_AfterSlash (
915
- User staker ,
918
+ /// Slashing invariants when the operator has been fully slashed for every strategy in the operator set
919
+ function check_FullySlashed_State (
916
920
User operator ,
917
- Withdrawal memory withdrawal ,
918
921
AllocateParams memory allocateParams ,
919
- SlashingParams memory slashingParams ,
920
- uint [] memory expectedTokens
921
- ) internal {
922
- IERC20 [] memory tokens = new IERC20 [](withdrawal.strategies.length );
923
-
924
- for (uint i; i < withdrawal.strategies.length ; i++ ) {
925
- IStrategy strat = withdrawal.strategies[i];
926
-
927
- bool isBeaconChainETHStrategy = strat == beaconChainETHStrategy;
928
-
929
- tokens[i] = isBeaconChainETHStrategy ? NATIVE_ETH : withdrawal.strategies[i].underlyingToken ();
930
-
931
- if (slashingParams.strategies.contains (strat)) {
932
- uint wadToSlash = slashingParams.wadsToSlash[slashingParams.strategies.indexOf (strat)];
933
-
934
- expectedTokens[i] -= expectedTokens[i]
935
- .mulWadRoundUp (allocateParams.newMagnitudes[i].mulWadRoundUp (wadToSlash));
936
-
937
- uint256 max = allocationManager.getMaxMagnitude (address (operator), strat);
938
-
939
- withdrawal.scaledShares[i] -= withdrawal.scaledShares[i].calcSlashedAmount (WAD, max);
940
-
941
- // Round down to the nearest gwei for beaconchain ETH strategy.
942
- if (isBeaconChainETHStrategy) {
943
- expectedTokens[i] -= expectedTokens[i] % 1 gwei ;
944
- }
945
- }
946
- }
947
-
948
- // Common checks
949
- assert_WithdrawalNotPending (delegationManager.calculateWithdrawalRoot (withdrawal), "staker withdrawal should no longer be pending " );
950
-
951
- // TODO FIXME
952
- // assert_Snap_Added_TokenBalances(staker, tokens, expectedTokens, "staker should have received expected tokens");
953
- assert_Snap_Unchanged_Staker_DepositShares (staker, "staker shares should not have changed " );
954
- assert_Snap_Removed_StrategyShares (withdrawal.strategies, withdrawal.scaledShares, "strategies should have total shares decremented " );
955
-
956
- // Checks specific to an operator that the Staker has delegated to
957
- if (operator != User (payable (0 ))) {
958
- if (operator != staker) {
959
- assert_Snap_Unchanged_TokenBalances (operator, "operator token balances should not have changed " );
960
- }
961
- assert_Snap_Unchanged_OperatorShares (operator, "operator shares should not have changed " );
962
- }
963
- }
964
-
965
- function check_Withdrawal_AsShares_State_AfterSlash (
966
- User staker ,
967
- User operator ,
968
- Withdrawal memory withdrawal ,
969
- AllocateParams memory allocateParams , // TODO - was this needed?
970
- SlashingParams memory slashingParams
922
+ SlashingParams memory slashParams
971
923
) internal {
972
- IERC20 [] memory tokens = new IERC20 [](withdrawal.strategies.length );
973
-
974
- for (uint i; i < withdrawal.strategies.length ; i++ ) {
975
- IStrategy strat = withdrawal.strategies[i];
976
-
977
- bool isBeaconChainETHStrategy = strat == beaconChainETHStrategy;
924
+ check_Base_Slashing_State (operator, allocateParams, slashParams);
978
925
979
- tokens[i] = isBeaconChainETHStrategy ? NATIVE_ETH : withdrawal.strategies[i].underlyingToken ();
980
-
981
- if (slashingParams.strategies.contains (strat)) {
982
- uint256 max = allocationManager.getMaxMagnitude (address (operator), strat);
983
-
984
- withdrawal.scaledShares[i] -= withdrawal.scaledShares[i].calcSlashedAmount (WAD, max);
985
- }
986
- }
987
-
988
- // Common checks applicable to both user and non-user operator types
989
- assert_WithdrawalNotPending (delegationManager.calculateWithdrawalRoot (withdrawal), "staker withdrawal should no longer be pending " );
990
- assert_Snap_Unchanged_TokenBalances (staker, "staker should not have any change in underlying token balances " );
991
- assert_Snap_Added_Staker_DepositShares (staker, withdrawal.strategies, withdrawal.scaledShares, "staker should have received expected shares " );
992
- assert_Snap_Unchanged_StrategyShares (withdrawal.strategies, "strategies should have total shares unchanged " );
993
-
994
- // Additional checks or handling for the non-user operator scenario
995
- if (operator != User (User (payable (0 )))) {
996
- if (operator != staker) {
997
- assert_Snap_Unchanged_TokenBalances (operator, "operator should not have any change in underlying token balances " );
998
- }
999
- }
926
+ assert_Snap_Removed_AllocatedSet (operator, allocateParams.operatorSet, "should not have updated allocated sets " );
927
+ assert_Snap_Removed_AllocatedStrats (operator, allocateParams.operatorSet, slashParams.strategies, "should not have updated allocated strategies " );
1000
928
}
1001
929
}
0 commit comments