Skip to content

Commit 5f342d7

Browse files
feat: add SlashingWithdrawalRouter (#1358)
**Motivation:** We want to hold slashed funds in escrow temporarily to maintain protocol security (prevent malicious actors from draining the contracts). **Modifications:** - Add `SlashingWithdrawalRouter`. **Result:** The `SlashingWithdrawalRouter` contract is added for managing slashed funds in the EigenLayer protocol. It provides a mechanism to handle the burning or redistribution of slashed shares after a delay period, ensuring proper handling of slashed funds while maintaining protocol security. --------- Co-authored-by: Yash Patil <[email protected]>
1 parent 416f144 commit 5f342d7

35 files changed

+2327
-1047
lines changed

script/deploy/devnet/deploy_from_scratch.s.sol

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import "../../../src/contracts/core/AVSDirectory.sol";
1414
import "../../../src/contracts/core/RewardsCoordinator.sol";
1515
import "../../../src/contracts/core/AllocationManager.sol";
1616
import "../../../src/contracts/permissions/PermissionController.sol";
17-
17+
import "../../../src/contracts/core/SlashingWithdrawalRouter.sol";
1818
import "../../../src/contracts/strategies/StrategyBaseTVLLimits.sol";
1919
import "../../../src/contracts/strategies/StrategyFactory.sol";
2020
import "../../../src/contracts/strategies/StrategyBase.sol";
@@ -63,6 +63,8 @@ contract DeployFromScratch is Script, Test {
6363
AllocationManager public allocationManager;
6464
PermissionController public permissionController;
6565
PermissionController public permissionControllerImplementation;
66+
SlashingWithdrawalRouter public slashingWithdrawalRouter;
67+
SlashingWithdrawalRouter public slashingWithdrawalRouterImplementation;
6668

6769
EmptyContract public emptyContract;
6870

@@ -214,6 +216,9 @@ contract DeployFromScratch is Script, Test {
214216
permissionController = PermissionController(
215217
address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), ""))
216218
);
219+
slashingWithdrawalRouter = SlashingWithdrawalRouter(
220+
address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), ""))
221+
);
217222

218223
// if on mainnet, use the ETH2 deposit contract address
219224
if (chainId == 1) ethPOSDeposit = IETHPOSDeposit(0x00000000219ab540356cBB839Cbe05303d7705Fa);
@@ -235,7 +240,8 @@ contract DeployFromScratch is Script, Test {
235240
SEMVER
236241
);
237242

238-
strategyManagerImplementation = new StrategyManager(delegation, eigenLayerPauserReg, SEMVER);
243+
strategyManagerImplementation =
244+
new StrategyManager(delegation, slashingWithdrawalRouter, eigenLayerPauserReg, SEMVER);
239245
avsDirectoryImplementation = new AVSDirectory(delegation, eigenLayerPauserReg, SEMVER);
240246
eigenPodManagerImplementation =
241247
new EigenPodManager(ethPOSDeposit, eigenPodBeacon, delegation, eigenLayerPauserReg, SEMVER);
@@ -264,6 +270,8 @@ contract DeployFromScratch is Script, Test {
264270
);
265271
permissionControllerImplementation = new PermissionController(SEMVER);
266272
strategyFactoryImplementation = new StrategyFactory(strategyManager, eigenLayerPauserReg, SEMVER);
273+
slashingWithdrawalRouterImplementation =
274+
new SlashingWithdrawalRouter(allocationManager, strategyManager, eigenLayerPauserReg, SEMVER);
267275

268276
// Third, upgrade the proxy contracts to use the correct implementation contracts and initialize them.
269277
{
@@ -537,9 +545,9 @@ contract DeployFromScratch is Script, Test {
537545

538546
function _verifyInitialOwners() internal view {
539547
require(strategyManager.owner() == executorMultisig, "strategyManager: owner not set correctly");
540-
require(delegation.owner() == executorMultisig, "delegation: owner not set correctly");
548+
// require(delegation.owner() == executorMultisig, "delegation: owner not set correctly");
541549
require(eigenPodManager.owner() == executorMultisig, "eigenPodManager: owner not set correctly");
542-
require(allocationManager.owner() == executorMultisig, "allocationManager: owner not set correctly");
550+
// require(allocationManager.owner() == executorMultisig, "allocationManager: owner not set correctly");
543551
require(eigenLayerProxyAdmin.owner() == executorMultisig, "eigenLayerProxyAdmin: owner not set correctly");
544552
require(eigenPodBeacon.owner() == executorMultisig, "eigenPodBeacon: owner not set correctly");
545553
require(strategyBeacon.owner() == executorMultisig, "strategyBeacon: owner not set correctly");

script/deploy/local/deploy_from_scratch.slashing.s.sol

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import "../../../src/contracts/core/AVSDirectory.sol";
1414
import "../../../src/contracts/core/RewardsCoordinator.sol";
1515
import "../../../src/contracts/core/AllocationManager.sol";
1616
import "../../../src/contracts/permissions/PermissionController.sol";
17+
import "../../../src/contracts/core/SlashingWithdrawalRouter.sol";
1718

1819
import "../../../src/contracts/strategies/StrategyBaseTVLLimits.sol";
1920

@@ -66,6 +67,8 @@ contract DeployFromScratch is Script, Test {
6667
AllocationManager public allocationManager;
6768
PermissionController public permissionControllerImplementation;
6869
PermissionController public permissionController;
70+
SlashingWithdrawalRouter public slashingWithdrawalRouter;
71+
SlashingWithdrawalRouter public slashingWithdrawalRouterImplementation;
6972

7073
EmptyContract public emptyContract;
7174

@@ -221,6 +224,9 @@ contract DeployFromScratch is Script, Test {
221224
permissionController = PermissionController(
222225
address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), ""))
223226
);
227+
slashingWithdrawalRouter = SlashingWithdrawalRouter(
228+
address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), ""))
229+
);
224230

225231
// if on mainnet, use the ETH2 deposit contract address
226232
if (chainId == 1) ethPOSDeposit = IETHPOSDeposit(0x00000000219ab540356cBB839Cbe05303d7705Fa);
@@ -241,7 +247,8 @@ contract DeployFromScratch is Script, Test {
241247
MIN_WITHDRAWAL_DELAY,
242248
SEMVER
243249
);
244-
strategyManagerImplementation = new StrategyManager(delegation, eigenLayerPauserReg, SEMVER);
250+
strategyManagerImplementation =
251+
new StrategyManager(delegation, slashingWithdrawalRouter, eigenLayerPauserReg, SEMVER);
245252
avsDirectoryImplementation = new AVSDirectory(delegation, eigenLayerPauserReg, SEMVER);
246253
eigenPodManagerImplementation =
247254
new EigenPodManager(ethPOSDeposit, eigenPodBeacon, delegation, eigenLayerPauserReg, SEMVER);
@@ -269,6 +276,8 @@ contract DeployFromScratch is Script, Test {
269276
SEMVER
270277
);
271278
permissionControllerImplementation = new PermissionController(SEMVER);
279+
slashingWithdrawalRouterImplementation =
280+
new SlashingWithdrawalRouter(allocationManager, strategyManager, eigenLayerPauserReg, SEMVER);
272281

273282
// Third, upgrade the proxy contracts to use the correct implementation contracts and initialize them.
274283
{
@@ -538,7 +547,7 @@ contract DeployFromScratch is Script, Test {
538547

539548
function _verifyInitialOwners() internal view {
540549
require(strategyManager.owner() == executorMultisig, "strategyManager: owner not set correctly");
541-
require(delegation.owner() == executorMultisig, "delegation: owner not set correctly");
550+
// require(delegation.owner() == executorMultisig, "delegation: owner not set correctly");
542551
require(eigenPodManager.owner() == executorMultisig, "eigenPodManager: owner not set correctly");
543552

544553
require(eigenLayerProxyAdmin.owner() == executorMultisig, "eigenLayerProxyAdmin: owner not set correctly");

script/output/devnet/SLASHING_deploy_from_scratch_deployment_data.json

Lines changed: 0 additions & 52 deletions
This file was deleted.

script/releases/v1.4.1-slashing/1-deployContracts.s.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ contract Deploy is EOADeployer {
144144

145145
DelegationManager delegation = Env.impl.delegationManager();
146146
vm.expectRevert(errInit);
147-
delegation.initialize(address(0), 0);
147+
delegation.initialize(0);
148148

149149
/// pods/
150150
EigenPod eigenPod = Env.impl.eigenPod();

script/releases/v1.4.1-slashing/3-executeUpgrade.s.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ contract Execute is QueueUpgrade {
8989

9090
DelegationManager delegation = Env.proxy.delegationManager();
9191
vm.expectRevert(errInit);
92-
delegation.initialize(address(0), 0);
93-
assertTrue(delegation.owner() == Env.executorMultisig(), "dm.owner invalid");
92+
delegation.initialize(0);
93+
// assertTrue(delegation.owner() == Env.executorMultisig(), "dm.owner invalid");
9494
assertTrue(delegation.paused() == 0, "dm.paused invalid");
9595

9696
EigenPodManager eigenPodManager = Env.proxy.eigenPodManager();

script/utils/ExistingDeploymentParser.sol

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import "../../src/contracts/core/AVSDirectory.sol";
1111
import "../../src/contracts/core/RewardsCoordinator.sol";
1212
import "../../src/contracts/core/AllocationManager.sol";
1313
import "../../src/contracts/permissions/PermissionController.sol";
14+
import "../../src/contracts/core/SlashingWithdrawalRouter.sol";
1415

1516
import "../../src/contracts/strategies/StrategyFactory.sol";
1617
import "../../src/contracts/strategies/StrategyBase.sol";
@@ -136,6 +137,10 @@ contract ExistingDeploymentParser is Script, Logger {
136137
StrategyBase public baseStrategyImplementation;
137138
StrategyBase public strategyFactoryBeaconImplementation;
138139

140+
/// @dev SlashingWithdrawalRouter
141+
SlashingWithdrawalRouter public slashingWithdrawalRouter;
142+
SlashingWithdrawalRouter public slashingWithdrawalRouterImplementation;
143+
139144
// Token
140145
ProxyAdmin public tokenProxyAdmin;
141146
IEigen public EIGEN;
@@ -524,7 +529,7 @@ contract ExistingDeploymentParser is Script, Logger {
524529
);
525530
// DelegationManager
526531
cheats.expectRevert(bytes("Initializable: contract is already initialized"));
527-
delegationManager.initialize(address(0), 0);
532+
delegationManager.initialize(0);
528533
// StrategyManager
529534
cheats.expectRevert(bytes("Initializable: contract is already initialized"));
530535
strategyManager.initialize(address(0), address(0), STRATEGY_MANAGER_INIT_PAUSED_STATUS);
@@ -605,7 +610,7 @@ contract ExistingDeploymentParser is Script, Logger {
605610
delegationManager.pauserRegistry() == eigenLayerPauserReg,
606611
"delegationManager: pauser registry not set correctly"
607612
);
608-
assertEq(delegationManager.owner(), executorMultisig, "delegationManager: owner not set correctly");
613+
// assertEq(delegationManager.owner(), executorMultisig, "delegationManager: owner not set correctly");
609614
assertEq(
610615
delegationManager.paused(),
611616
DELEGATION_MANAGER_INIT_PAUSED_STATUS,

0 commit comments

Comments
 (0)