@@ -202,15 +202,16 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
202
202
view
203
203
{
204
204
for (uint i = 0 ; i < strategies.length ; i++ ) {
205
- IStrategy strat = strategies[i];
205
+ assert_HasUnderlyingTokenBalance (user, strategies[i], expectedBalances[i], err);
206
+ }
207
+ }
206
208
207
- uint expectedBalance = expectedBalances[i];
208
- uint tokenBalance;
209
- if (strat == BEACONCHAIN_ETH_STRAT) tokenBalance = address (user).balance;
210
- else tokenBalance = strat .underlyingToken ().balanceOf (address (user));
209
+ function assert_HasUnderlyingTokenBalance (User user , IStrategy strategy , uint expectedBalance , string memory err ) internal view {
210
+ uint tokenBalance;
211
+ if (strategy == BEACONCHAIN_ETH_STRAT) tokenBalance = address (user).balance;
212
+ else tokenBalance = strategy .underlyingToken ().balanceOf (address (user));
211
213
212
- assertApproxEqAbs (expectedBalance, tokenBalance, 1 , err);
213
- }
214
+ assertApproxEqAbs (expectedBalance, tokenBalance, 1 , err);
214
215
}
215
216
216
217
function assert_HasNoUnderlyingTokenBalance (User user , IStrategy[] memory strategies , string memory err ) internal view {
@@ -1408,17 +1409,38 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
1408
1409
OperatorSet memory operatorSet ,
1409
1410
User operator ,
1410
1411
SlashingParams memory params ,
1412
+ uint slashId ,
1411
1413
string memory err
1412
1414
) internal {
1413
1415
uint [] memory curShares = _getOperatorShares (operator, params.strategies);
1414
1416
uint [] memory prevShares = _getPrevOperatorShares (operator, params.strategies);
1415
1417
1416
1418
for (uint i = 0 ; i < params.strategies.length ; i++ ) {
1417
- uint curBurnable = _getBurnableShares ( params.strategies[i]);
1418
- uint prevBurnable = _getPrevBurnableShares ( params.strategies[i]);
1419
+ uint curBurnable = _getBurnOrRedistributableShares (operatorSet, slashId, params.strategies[i]);
1420
+ uint prevBurnable = _getPrevBurnOrRedistributableShares (operatorSet, slashId, params.strategies[i]);
1419
1421
uint slashedAtLeast = prevShares[i] - curShares[i];
1420
1422
// Not factoring in slashable shares in queue here, because that gets more complex (TODO)
1421
1423
assertTrue (curBurnable >= (prevBurnable + slashedAtLeast), err);
1424
+
1425
+ // TODO: Improve this check in the future, it's not very optimized.
1426
+ // In the future, we can simply use a flag to communicate whether the operator set is redistributable.
1427
+ if (curShares[i] == prevShares[i]) continue ;
1428
+ bool flag = false ;
1429
+ for (uint j = 0 ; j < params.strategies.length ; j++ ) {
1430
+ if (params.strategies[j] == BEACONCHAIN_ETH_STRAT) flag = true ;
1431
+ }
1432
+ if (flag) continue ;
1433
+
1434
+ assertTrue (_getIsPendingOperatorSet (operatorSet), "operator set should be pending " );
1435
+
1436
+ assertTrue (_getIsPendingSlashId (operatorSet, slashId), "slash id should be pending " );
1437
+ assertFalse (_getPrevIsPendingSlashId (operatorSet, slashId), "slash id should not be pending " );
1438
+
1439
+ assertEq (_getEscrowStartBlock (operatorSet, slashId), block .number , "escrow start block should be current block " );
1440
+ assertEq (_getPrevEscrowStartBlock (operatorSet, slashId), 0 , "escrow start block should be 0 " );
1441
+
1442
+ assertTrue (_getIsDeployedSlashEscrow (operatorSet, slashId), "escrow should be deployed " );
1443
+ assertFalse (_getPrevIsDeployedSlashEscrow (operatorSet, slashId), "escrow should not be deployed " );
1422
1444
}
1423
1445
}
1424
1446
@@ -2215,6 +2237,22 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
2215
2237
}
2216
2238
}
2217
2239
2240
+ function _genSlashing_SingleStrategy (User operator , OperatorSet memory operatorSet , IStrategy strategy )
2241
+ internal
2242
+ returns (SlashingParams memory params )
2243
+ {
2244
+ params.operator = address (operator);
2245
+ params.operatorSetId = operatorSet.id;
2246
+ params.description = "_genSlashing_SingleStrategy " ;
2247
+ params.strategies = strategy.toArray ();
2248
+ params.wadsToSlash = new uint [](params.strategies.length );
2249
+
2250
+ // slash 100%
2251
+ for (uint i = 0 ; i < params.wadsToSlash.length ; i++ ) {
2252
+ params.wadsToSlash[i] = 1e18 ;
2253
+ }
2254
+ }
2255
+
2218
2256
function _genSlashing_Custom (User operator , OperatorSet memory operatorSet , uint wadsToSlash )
2219
2257
internal
2220
2258
returns (SlashingParams memory params )
@@ -2533,6 +2571,10 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
2533
2571
cheats.roll (latest + 1 );
2534
2572
}
2535
2573
2574
+ function _rollBlocksForCompleteSlashEscrow () internal {
2575
+ cheats.roll (block .number + INITIAL_GLOBAL_DELAY_BLOCKS + 1 );
2576
+ }
2577
+
2536
2578
/// @dev Uses timewarp modifier to get the operator set strategy allocations at the last snapshot.
2537
2579
function _getPrevAllocations (User operator , OperatorSet memory operatorSet , IStrategy[] memory strategies )
2538
2580
internal
@@ -2709,12 +2751,54 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
2709
2751
return allocationManager.isMemberOfOperatorSet (address (operator), operatorSet);
2710
2752
}
2711
2753
2712
- function _getPrevBurnableShares (IStrategy strategy ) internal timewarp returns (uint ) {
2713
- return _getBurnableShares (strategy);
2754
+ function _getPrevBurnOrRedistributableShares (OperatorSet memory operatorSet , uint slashId , IStrategy strategy )
2755
+ internal
2756
+ timewarp
2757
+ returns (uint )
2758
+ {
2759
+ return _getBurnOrRedistributableShares (operatorSet, slashId, strategy);
2760
+ }
2761
+
2762
+ function _getBurnOrRedistributableShares (OperatorSet memory operatorSet , uint slashId , IStrategy strategy )
2763
+ internal
2764
+ view
2765
+ returns (uint )
2766
+ {
2767
+ return strategy == beaconChainETHStrategy
2768
+ ? eigenPodManager.burnableETHShares ()
2769
+ : strategyManager.getBurnOrRedistributableShares (operatorSet, slashId, strategy);
2770
+ }
2771
+
2772
+ function _getPrevIsPendingOperatorSet (OperatorSet memory operatorSet ) internal timewarp returns (bool ) {
2773
+ return _getIsPendingOperatorSet (operatorSet);
2774
+ }
2775
+
2776
+ function _getIsPendingOperatorSet (OperatorSet memory operatorSet ) internal view returns (bool ) {
2777
+ return slashEscrowFactory.isPendingOperatorSet (operatorSet);
2778
+ }
2779
+
2780
+ function _getPrevIsPendingSlashId (OperatorSet memory operatorSet , uint slashId ) internal timewarp returns (bool ) {
2781
+ return _getIsPendingSlashId (operatorSet, slashId);
2782
+ }
2783
+
2784
+ function _getIsPendingSlashId (OperatorSet memory operatorSet , uint slashId ) internal view returns (bool ) {
2785
+ return slashEscrowFactory.isPendingSlashId (operatorSet, slashId);
2786
+ }
2787
+
2788
+ function _getPrevEscrowStartBlock (OperatorSet memory operatorSet , uint slashId ) internal timewarp returns (uint ) {
2789
+ return _getEscrowStartBlock (operatorSet, slashId);
2790
+ }
2791
+
2792
+ function _getEscrowStartBlock (OperatorSet memory operatorSet , uint slashId ) internal view returns (uint ) {
2793
+ return slashEscrowFactory.getEscrowStartBlock (operatorSet, slashId);
2794
+ }
2795
+
2796
+ function _getPrevIsDeployedSlashEscrow (OperatorSet memory operatorSet , uint slashId ) internal timewarp returns (bool ) {
2797
+ return _getIsDeployedSlashEscrow (operatorSet, slashId);
2714
2798
}
2715
2799
2716
- function _getBurnableShares (IStrategy strategy ) internal view returns (uint ) {
2717
- return strategy == beaconChainETHStrategy ? eigenPodManager. burnableETHShares () : strategyManager. getBurnableShares (strategy );
2800
+ function _getIsDeployedSlashEscrow (OperatorSet memory operatorSet , uint slashId ) internal view returns (bool ) {
2801
+ return slashEscrowFactory. isDeployedSlashEscrow (operatorSet, slashId );
2718
2802
}
2719
2803
2720
2804
function _getPrevSlashableSharesInQueue (User operator , IStrategy[] memory strategies ) internal timewarp returns (uint [] memory ) {
0 commit comments