Skip to content

Commit 1feea71

Browse files
authored
test: redistribution upgrade (#1410)
**Motivation:** We need to sanity test that slashes completed prior to redistribution can be burned after redistribution. **Modifications:** - Add redistribution upgrade test which tests: 1. A slash prior to redistribution can have its shares burned after the upgrade 2. A slash prior to redistribution can have its shares burned prior to upgrade & storage is cleared - Remove all User_m2/m1 functionality **Result:** Basic upgrade test.
1 parent cb68310 commit 1feea71

18 files changed

+222
-1226
lines changed

script/configs/mainnet/mainnet-addresses.config.json

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,35 @@
11
{
2-
"lastUpdated": "v0.4.3-mainnet-foundation-incentives",
2+
"lastUpdated": "v1.4.1-mainnet-prooftra",
33
"addresses": {
4+
"allocationManager": "0x948a420b8CC1d6BFd0B6087C2E7c344a2CD0bc39",
5+
"allocationManagerImplementation": "0x740058839A1668Af5700e5d7B062007275e77D25",
46
"avsDirectory": "0x135dda560e946695d6f155dacafc6f1f25c1f5af",
5-
"avsDirectoryImplementation": "0xdabdb3cd346b7d5f5779b0b614ede1cc9dcba5b7",
7+
"avsDirectoryImplementation": "0xA396D855D70e1A1ec1A0199ADB9845096683B6A2",
68
"beaconOracle": "0x343907185b71aDF0eBa9567538314396aa985442",
7-
"baseStrategyImplementation": "0xdfdA04f980bE6A64E3607c95Ca26012Ab9aA46d3",
9+
"baseStrategyImplementation": "0x0EC17ef9c00F360DB28CA8008684a4796b11E456",
810
"delayedWithdrawalRouter": "0x7Fe7E9CC0F274d2435AD5d56D5fa73E47F6A23D8",
911
"delayedWithdrawalRouterImplementation": "0x4bb6731b02314d40abbffbc4540f508874014226",
1012
"delegationManager": "0x39053D51B77DC0d36036Fc1fCc8Cb819df8Ef37A",
11-
"delegationManagerImplementation": "0x1784be6401339fc0fedf7e9379409f5c1bfe9dda",
13+
"delegationManagerImplementation": "0xA75112d1df37FA53a431525CD47A7d7faCEA7E73",
1214
"eigenLayerPauserReg": "0x0c431C66F4dE941d089625E5B423D00707977060",
1315
"eigenLayerProxyAdmin": "0x8b9566AdA63B64d1E1dcF1418b43fd1433b72444",
1416
"eigenPodBeacon": "0x5a2a4F2F3C18f09179B6703e63D9eDD165909073",
15-
"eigenPodImplementation": "0x6D225e974Fa404D25Ffb84eD6E242Ffa18eF6430",
17+
"eigenPodImplementation": "0xe2E2dB234b0FFB9AFe41e52dB7d3c2B8585646c3",
1618
"eigenPodManager": "0x91E677b07F7AF907ec9a428aafA9fc14a0d3A338",
17-
"eigenPodManagerImplementation": "0x731A0aD160e407393Ff662231Add6Dd145AD3FEa",
19+
"eigenPodManagerImplementation": "0x8dB49233e3b7691D68745A31e4A0Cd9Cf924B7E9",
1820
"emptyContract": "0x1f96861fEFa1065a5A96F20Deb6D8DC3ff48F7f9",
21+
"permissionController": "0x25E5F8B1E7aDf44518d35D5B2271f114e081f0E5",
22+
"permissionControllerImplementation": "0xe7f3705c9Addf2DE14e03C345fA982CAb2c1C6B1",
1923
"rewardsCoordinator": "0x7750d328b314EfFa365A0402CcfD489B80B0adda",
20-
"rewardsCoordinatorImplementation": "0xb6738A8E7793D44c5895B6A6F2a62F6bF86Ba8d2",
24+
"rewardsCoordinatorImplementation": "0xa505c0116aD65071F0130061F94745b7853220aB",
2125
"slasher": "0xD92145c07f8Ed1D392c1B88017934E301CC1c3Cd",
2226
"slasherImplementation": "0xf3234220163a757edf1e11a8a085638d9b236614",
2327
"strategyManager": "0x858646372CC42E1A627fcE94aa7A7033e7CF075A",
24-
"strategyManagerImplementation": "0x70f44c13944d49a236e3cd7a94f48f5dab6c619b",
28+
"strategyManagerImplementation": "0xba4b2b8A076851A3044882493C2e36503d50b925",
2529
"strategyFactory": "0x5e4C39Ad7A3E881585e383dB9827EB4811f6F647",
26-
"strategyFactoryImplementation": "0x3e07cc2D34C8E0965f5BA45Ac1E960e535155c74",
30+
"strategyFactoryImplementation": "0x1b97d8F963179C0e17E5F3d85cdfd9a31A49bc66",
2731
"strategyFactoryBeacon": "0x0ed6703C298d28aE0878d1b28e88cA87F9662fE9",
28-
"strategyFactoryBeaconImplementation": "0xe9FA8F904d97854C7389b68923262ADCC6C27827",
32+
"strategyFactoryBeaconImplementation": "0x0EC17ef9c00F360DB28CA8008684a4796b11E456",
2933
"numStrategiesDeployed": 12,
3034
"strategies": {
3135
"stETH": "0x93c4b944D05dfe6df7645A86cd2206016c51564D",
@@ -62,20 +66,20 @@
6266
"EIGENImpl": "0x17f56E911C279bad67eDC08acbC9cf3DC4eF26A0",
6367
"bEIGENImpl": "0xF2b225815F70c9b327DC9db758A36c92A4279b17",
6468
"eigenStrategy": "0xaCB55C530Acdb2849e6d4f36992Cd8c9D50ED8F7",
65-
"eigenStrategyImpl": "0x27e7a3a81741b9fcc5ad7edcbf9f8a72a5c00428"
69+
"eigenStrategyImpl": "0x90B074DDD680bD06C72e28b09231A0F848205729"
6670
}
6771
},
6872
"numStrategies": 12,
6973
"chainInfo": {
7074
"chainId": 1,
71-
"deploymentBlock": 20571838
75+
"deploymentBlock": 22434239
7276
},
7377
"parameters": {
7478
"communityMultisig": "0xFEA47018D632A77bA579846c840d5706705Dc598",
7579
"executorMultisig": "0x369e6F597e22EaB55fFb173C6d9cD234BD699111",
7680
"operationsMultisig": "0xBE1685C81aA44FF9FB319dD389addd9374383e90",
7781
"pauserMultisig": "0x5050389572f2d220ad927CcbeA0D406831012390",
7882
"timelock": "0xA6Db1A8C5a981d1536266D2a393c5F8dDb210EAF",
79-
"semver": "v0.5.4"
83+
"semver": "v1.4.1"
8084
}
8185
}

script/utils/ExistingDeploymentParser.sol

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -229,25 +229,10 @@ contract ExistingDeploymentParser is Script, Logger {
229229
)
230230
);
231231

232-
allocationManagerImplementation = new AllocationManager(
233-
delegationManager,
234-
eigenLayerPauserReg,
235-
permissionController,
236-
DEALLOCATION_DELAY,
237-
ALLOCATION_CONFIGURATION_DELAY,
238-
SEMVER
239-
);
240-
allocationManager = AllocationManager(
241-
address(
242-
new TransparentUpgradeableProxy(
243-
address(allocationManagerImplementation), address(eigenLayerProxyAdmin), ""
244-
)
245-
)
246-
);
247-
248-
// // AllocationManager
249-
// allocationManager = AllocationManager(json.readAddress(".addresses.allocationManager"));
250-
// allocationManagerImplementation = json.readAddress(".addresses.allocationManagerImplementation");
232+
// AllocationManager
233+
allocationManager = AllocationManager(json.readAddress(".addresses.allocationManager"));
234+
allocationManagerImplementation =
235+
AllocationManager(json.readAddress(".addresses.allocationManagerImplementation"));
251236

252237
// AVSDirectory
253238
avsDirectory = AVSDirectory(json.readAddress(".addresses.avsDirectory"));
@@ -258,9 +243,10 @@ contract ExistingDeploymentParser is Script, Logger {
258243
delegationManagerImplementation =
259244
DelegationManager(json.readAddress(".addresses.delegationManagerImplementation"));
260245

261-
// // PermissionController
262-
// permissionController = PermissionController(json.readAddress(".addresses.permissionController"));
263-
// permissionControllerImplementation = json.readAddress(".addresses.permissionControllerImplementation");
246+
// PermissionController
247+
permissionController = PermissionController(json.readAddress(".addresses.permissionController"));
248+
permissionControllerImplementation =
249+
PermissionController(json.readAddress(".addresses.permissionControllerImplementation"));
264250

265251
// RewardsCoordinator
266252
rewardsCoordinator = RewardsCoordinator(json.readAddress(".addresses.rewardsCoordinator"));

src/test/integration/IntegrationBase.t.sol

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import "src/test/integration/TypeImporter.t.sol";
1313
import "src/test/integration/IntegrationDeployer.t.sol";
1414
import "src/test/integration/TimeMachine.t.sol";
1515
import "src/test/integration/users/User.t.sol";
16-
import "src/test/integration/users/User_M1.t.sol";
1716

1817
abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
1918
using StdStyle for *;
@@ -75,16 +74,10 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
7574
uint[] memory addedShares = _calculateExpectedShares(strategies, tokenBalances);
7675
operator.depositIntoEigenlayer(strategies, tokenBalances);
7776

78-
/// Registration flow differs for M2 vs Slashing release
79-
if (!isUpgraded) {
80-
User_M2(payable(operator)).registerAsOperator_M2();
77+
/// Registration flow is the same pre and post redistribution upgrade
78+
operator.registerAsOperator();
8179

82-
operatorsToMigrate.push(operator);
83-
} else {
84-
operator.registerAsOperator();
85-
86-
rollForward({blocks: ALLOCATION_CONFIGURATION_DELAY + 1});
87-
}
80+
rollForward({blocks: ALLOCATION_CONFIGURATION_DELAY + 1});
8881

8982
assert_Snap_Added_OperatorShares(operator, strategies, addedShares, "_newRandomOperator: failed to award shares to operator");
9083
assertTrue(delegationManager.isOperator(address(operator)), "_newRandomOperator: operator should be registered");
@@ -96,16 +89,10 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
9689
function _newRandomOperator_NoAssets() internal returns (User) {
9790
User operator = _randUser_NoAssets(_getOperatorName());
9891

99-
/// Registration flow differs for M2 vs Slashing release
100-
if (!isUpgraded) {
101-
User_M2(payable(operator)).registerAsOperator_M2();
92+
/// Registration flow is the same pre and post redistribution upgrade
93+
operator.registerAsOperator();
10294

103-
operatorsToMigrate.push(operator);
104-
} else {
105-
operator.registerAsOperator();
106-
107-
rollForward({blocks: ALLOCATION_CONFIGURATION_DELAY + 1});
108-
}
95+
rollForward({blocks: ALLOCATION_CONFIGURATION_DELAY + 1});
10996

11097
assertTrue(delegationManager.isOperator(address(operator)), "_newRandomOperator: operator should be registered");
11198
assertEq(delegationManager.delegatedTo(address(operator)), address(operator), "_newRandomOperator: should be self-delegated");
@@ -117,7 +104,7 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
117104
numStakers++;
118105

119106
string memory stakerNum = cheats.toString(numStakers);
120-
string memory namePrefix = isUpgraded ? "staker" : "m2-staker";
107+
string memory namePrefix = isUpgraded ? "staker" : "pre-redistribution-staker";
121108

122109
return string.concat(namePrefix, stakerNum);
123110
}
@@ -127,7 +114,7 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
127114
numOperators++;
128115

129116
string memory operatorNum = cheats.toString(numOperators);
130-
string memory namePrefix = isUpgraded ? "operator" : "m2-operator";
117+
string memory namePrefix = isUpgraded ? "operator" : "pre-redistribution-operator";
131118

132119
return string.concat(namePrefix, operatorNum);
133120
}
@@ -2431,9 +2418,7 @@ abstract contract IntegrationBase is IntegrationDeployer, TypeImporter {
24312418

24322419
function _calcNativeETHOperatorShareDelta(User staker, int shareDelta) internal view returns (int) {
24332420
// TODO: Maybe we update parent method to have an M2 and Slashing version?
2434-
int curPodOwnerShares;
2435-
if (!isUpgraded) curPodOwnerShares = IEigenPodManager_DeprecatedM2(address(eigenPodManager)).podOwnerShares(address(staker));
2436-
else curPodOwnerShares = eigenPodManager.podOwnerDepositShares(address(staker));
2421+
int curPodOwnerShares = eigenPodManager.podOwnerDepositShares(address(staker));
24372422
int newPodOwnerShares = curPodOwnerShares + shareDelta;
24382423

24392424
if (curPodOwnerShares <= 0) {

src/test/integration/IntegrationChecks.t.sol

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ pragma solidity ^0.8.27;
33

44
import "src/test/integration/IntegrationBase.t.sol";
55
import "src/test/integration/users/User.t.sol";
6-
import "src/test/integration/users/User_M1.t.sol";
7-
import "src/test/integration/users/User_M2.t.sol";
86

97
/// @notice Contract that provides utility functions to reuse common test blocks & checks
108
contract IntegrationCheckUtils is IntegrationBase {

src/test/integration/IntegrationDeployer.t.sol

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ import "src/test/integration/mocks/BeaconChainMock.t.sol";
2626

2727
import "src/test/integration/users/AVS.t.sol";
2828
import "src/test/integration/users/User.t.sol";
29-
import "src/test/integration/users/User_M1.t.sol";
30-
import "src/test/integration/users/User_M2.t.sol";
3129

3230
import "script/utils/ExistingDeploymentParser.sol";
3331

@@ -39,7 +37,7 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
3937

4038
// Fork ids for specific fork tests
4139
bool isUpgraded;
42-
uint mainnetForkBlock = 21_616_692; // Post Protocol Council upgrade
40+
uint mainnetForkBlock = 22_514_370; // Post Pectra Compatibility Upgrade
4341

4442
string version = "9.9.9";
4543

@@ -591,12 +589,13 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser {
591589
} else {
592590
revert("_randUser: unimplemented userType");
593591
}
592+
// Leaving this if statement for future upgraded users
594593
} else if (forkType == MAINNET && !isUpgraded) {
595594
if (userType == DEFAULT) {
596-
user = User(new User_M2(name));
595+
user = new User(name);
597596
} else if (userType == ALT_METHODS) {
598597
// User will use nonstandard methods like `depositIntoStrategyWithSignature`
599-
user = User(new User_M2(name));
598+
user = User(new User_AltMethods(name));
600599
} else {
601600
revert("_randUser: unimplemented userType");
602601
}

src/test/integration/UpgradeTest.t.sol

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ pragma solidity ^0.8.27;
33

44
import "src/test/integration/IntegrationDeployer.t.sol";
55
import "src/test/integration/IntegrationChecks.t.sol";
6-
import "src/test/integration/mocks/BeaconChainMock_Deneb.t.sol";
76

87
abstract contract UpgradeTest is IntegrationCheckUtils {
98
/// Only run upgrade tests on mainnet forks
@@ -13,9 +12,6 @@ abstract contract UpgradeTest is IntegrationCheckUtils {
1312
} else {
1413
isUpgraded = false;
1514
super.setUp();
16-
17-
// Use Deneb Beacon Chain Mock as Pectra state is not live on mainnet
18-
beaconChain = BeaconChainMock(new BeaconChainMock_DenebForkable(eigenPodManager, BEACON_GENESIS_TIME));
1915
}
2016
}
2117

@@ -24,31 +20,13 @@ abstract contract UpgradeTest is IntegrationCheckUtils {
2420
require(forkType == MAINNET, "_upgradeEigenLayerContracts: somehow running upgrade test locally");
2521
require(!isUpgraded, "_upgradeEigenLayerContracts: already performed upgrade");
2622

27-
emit log("_upgradeEigenLayerContracts: upgrading mainnet to slashing");
23+
emit log("_upgradeEigenLayerContracts: upgrading mainnet to redistribution");
2824

2925
_upgradeMainnetContracts();
30-
_handlePectraFork();
31-
32-
// Bump block.timestamp forward to allow verifyWC proofs for migrated pods
33-
emit log("advancing block time to start of next epoch:");
34-
35-
beaconChain.advanceEpoch_NoRewards();
3626

3727
emit log("======");
3828

3929
isUpgraded = true;
40-
emit log("_upgradeEigenLayerContracts: slashing upgrade complete");
41-
}
42-
43-
// Set the fork timestamp sufficiently in the future to keep using Deneb proofs
44-
// `Prooftra.t.sol` will handle the Deneb -> Pectra transition
45-
function _handlePectraFork() internal {
46-
// 1. Set proof timestamp setter to operations multisig
47-
cheats.prank(eigenPodManager.owner());
48-
eigenPodManager.setProofTimestampSetter(address(operationsMultisig));
49-
50-
// 2. Set Proof timestamp
51-
cheats.prank(eigenPodManager.proofTimestampSetter());
52-
eigenPodManager.setPectraForkTimestamp(type(uint64).max);
30+
emit log("_upgradeEigenLayerContracts: redistribution upgrade complete");
5331
}
5432
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.27;
3+
4+
import "src/contracts/interfaces/IStrategy.sol";
5+
6+
/**
7+
* @notice Interface of the allocationManager prior to redistribution.
8+
* @dev The interface remains the exact same, except `SlashOperator` does not return the slashID or shares
9+
* @dev This interface is the minimal possibl interface needed for the redistribution upgrade test
10+
*/
11+
interface IAllocationManager_PreRedistribution {
12+
/**
13+
* @notice Struct containing parameters to slashing
14+
* @param operator the address to slash
15+
* @param operatorSetId the ID of the operatorSet the operator is being slashed on behalf of
16+
* @param strategies the set of strategies to slash
17+
* @param wadsToSlash the parts in 1e18 to slash, this will be proportional to the operator's
18+
* slashable stake allocation for the operatorSet
19+
* @param description the description of the slashing provided by the AVS for legibility
20+
*/
21+
struct SlashingParams {
22+
address operator;
23+
uint32 operatorSetId;
24+
IStrategy[] strategies;
25+
uint[] wadsToSlash;
26+
string description;
27+
}
28+
29+
/**
30+
* @notice Called by an AVS to slash an operator in a given operator set. The operator must be registered
31+
* and have slashable stake allocated to the operator set.
32+
*
33+
* @param avs The AVS address initiating the slash.
34+
* @param params The slashing parameters, containing:
35+
* - operator: The operator to slash.
36+
* - operatorSetId: The ID of the operator set the operator is being slashed from.
37+
* - strategies: Array of strategies to slash allocations from (must be in ascending order).
38+
* - wadsToSlash: Array of proportions to slash from each strategy (must be between 0 and 1e18).
39+
* - description: Description of why the operator was slashed.
40+
*
41+
* @dev For each strategy:
42+
* 1. Reduces the operator's current allocation magnitude by wadToSlash proportion.
43+
* 2. Reduces the strategy's max and encumbered magnitudes proportionally.
44+
* 3. If there is a pending deallocation, reduces it proportionally.
45+
* 4. Updates the operator's shares in the DelegationManager.
46+
*
47+
* @dev Small slashing amounts may not result in actual token burns due to
48+
* rounding, which will result in small amounts of tokens locked in the contract
49+
* rather than fully burning through the burn mechanism.
50+
*/
51+
function slashOperator(address avs, SlashingParams calldata params) external;
52+
}

0 commit comments

Comments
 (0)