diff --git a/test/unit/InstantSlasher.t.sol b/test/unit/InstantSlasher.t.sol index 72e15e8d..ed26e0bf 100644 --- a/test/unit/InstantSlasher.t.sol +++ b/test/unit/InstantSlasher.t.sol @@ -50,14 +50,13 @@ import {StakeRegistry} from "../../src/StakeRegistry.sol"; import {BLSApkRegistry} from "../../src/BLSApkRegistry.sol"; import {IndexRegistry} from "../../src/IndexRegistry.sol"; import {SocketRegistry} from "../../src/SocketRegistry.sol"; +import {MiddlewareDeployLib} from "../utils/MiddlewareDeployLib.sol"; contract InstantSlasherTest is Test { InstantSlasher public instantSlasher; - InstantSlasher public instantSlasherImplementation; ProxyAdmin public proxyAdmin; EmptyContract public emptyContract; SlashingRegistryCoordinator public slashingRegistryCoordinator; - SlashingRegistryCoordinator public slashingRegistryCoordinatorImplementation; CoreDeploymentLib.DeploymentData public coreDeployment; PauserRegistry public pauserRegistry; ERC20Mock public mockToken; @@ -149,108 +148,51 @@ contract InstantSlasherTest is Test { IERC20(address(mockToken)) ) ); - - // Deploy empty proxies for all registries - stakeRegistry = StakeRegistry( - address( - new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "") - ) - ); - - blsApkRegistry = BLSApkRegistry( - address( - new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "") - ) - ); - - indexRegistry = IndexRegistry( - address( - new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "") - ) - ); - - socketRegistry = SocketRegistry( - address( - new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "") - ) - ); - - slashingRegistryCoordinatorImplementation = new SlashingRegistryCoordinator( - IStakeRegistry(address(stakeRegistry)), - IBLSApkRegistry(address(blsApkRegistry)), - IIndexRegistry(address(indexRegistry)), - ISocketRegistry(address(socketRegistry)), - IAllocationManager(coreDeployment.allocationManager), - IPauserRegistry(address(pauserRegistry)) - ); - - slashingRegistryCoordinator = SlashingRegistryCoordinator( - address( - new TransparentUpgradeableProxy( - address(slashingRegistryCoordinatorImplementation), address(proxyAdmin), "" - ) - ) - ); - - // Deploy registry implementations pointing to the coordinator - StakeRegistry stakeRegistryImplementation = new StakeRegistry( - ISlashingRegistryCoordinator(address(slashingRegistryCoordinator)), - IDelegationManager(coreDeployment.delegationManager), - IAVSDirectory(coreDeployment.avsDirectory), - IAllocationManager(coreDeployment.allocationManager) - ); - BLSApkRegistry blsApkRegistryImplementation = - new BLSApkRegistry(ISlashingRegistryCoordinator(address(slashingRegistryCoordinator))); - IndexRegistry indexRegistryImplementation = - new IndexRegistry(ISlashingRegistryCoordinator(address(slashingRegistryCoordinator))); - SocketRegistry socketRegistryImplementation = - new SocketRegistry(IRegistryCoordinator(address(slashingRegistryCoordinator))); - - // Upgrade all registry proxies - proxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(stakeRegistry))), - address(stakeRegistryImplementation) - ); - proxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(blsApkRegistry))), - address(blsApkRegistryImplementation) - ); - proxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(indexRegistry))), - address(indexRegistryImplementation) - ); - proxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(socketRegistry))), - address(socketRegistryImplementation) - ); - - // Initialize the SlashingRegistryCoordinator first - slashingRegistryCoordinator.initialize( - proxyAdminOwner, churnApprover, ejector, 0, serviceManager - ); - vm.stopPrank(); - instantSlasherImplementation = new InstantSlasher( - IAllocationManager(coreDeployment.allocationManager), - ISlashingRegistryCoordinator(slashingRegistryCoordinator), - slasher - ); + MiddlewareDeployLib.MiddlewareDeployConfig memory middlewareConfig; + middlewareConfig.instantSlasher.initialOwner = proxyAdminOwner; + middlewareConfig.instantSlasher.slasher = slasher; + middlewareConfig.slashingRegistryCoordinator.initialOwner = proxyAdminOwner; + middlewareConfig.slashingRegistryCoordinator.churnApprover = churnApprover; + middlewareConfig.slashingRegistryCoordinator.ejector = ejector; + middlewareConfig.slashingRegistryCoordinator.initPausedStatus = 0; + middlewareConfig.slashingRegistryCoordinator.serviceManager = serviceManager; + middlewareConfig.socketRegistry.initialOwner = proxyAdminOwner; + middlewareConfig.indexRegistry.initialOwner = proxyAdminOwner; + middlewareConfig.stakeRegistry.initialOwner = proxyAdminOwner; + middlewareConfig.stakeRegistry.minimumStake = 1 ether; + middlewareConfig.stakeRegistry.strategyParams = 0; + middlewareConfig.stakeRegistry.delegationManager = coreDeployment.delegationManager; + middlewareConfig.stakeRegistry.avsDirectory = coreDeployment.avsDirectory; + { + IStakeRegistryTypes.StrategyParams[] memory stratParams = + new IStakeRegistryTypes.StrategyParams[](1); + stratParams[0] = + IStakeRegistryTypes.StrategyParams({strategy: mockStrategy, multiplier: 1 ether}); + middlewareConfig.stakeRegistry.strategyParamsArray = stratParams; + } + middlewareConfig.stakeRegistry.lookAheadPeriod = 0; + middlewareConfig.stakeRegistry.stakeType = IStakeRegistryTypes.StakeType(1); + middlewareConfig.blsApkRegistry.initialOwner = proxyAdminOwner; vm.startPrank(proxyAdminOwner); - instantSlasher = InstantSlasher( - address( - new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "") - ) - ); - - proxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(instantSlasher))), - address(instantSlasherImplementation) + MiddlewareDeployLib.MiddlewareDeployData memory middlewareDeployments = MiddlewareDeployLib + .deployMiddleware( + address(proxyAdmin), + coreDeployment.allocationManager, + address(pauserRegistry), + middlewareConfig ); vm.stopPrank(); - instantSlasher.initialize(slasher); + instantSlasher = InstantSlasher(middlewareDeployments.instantSlasher); + slashingRegistryCoordinator = + SlashingRegistryCoordinator(middlewareDeployments.slashingRegistryCoordinator); + stakeRegistry = StakeRegistry(middlewareDeployments.stakeRegistry); + blsApkRegistry = BLSApkRegistry(middlewareDeployments.blsApkRegistry); + indexRegistry = IndexRegistry(middlewareDeployments.indexRegistry); + socketRegistry = SocketRegistry(middlewareDeployments.socketRegistry); vm.startPrank(serviceManager); PermissionController(coreDeployment.permissionController).setAppointee( @@ -295,12 +237,7 @@ contract InstantSlasherTest is Test { vm.stopPrank(); vm.label(address(instantSlasher), "InstantSlasher Proxy"); - vm.label(address(instantSlasherImplementation), "InstantSlasher Implementation"); vm.label(address(slashingRegistryCoordinator), "SlashingRegistryCoordinator Proxy"); - vm.label( - address(slashingRegistryCoordinatorImplementation), - "SlashingRegistryCoordinator Implementation" - ); vm.label(address(proxyAdmin), "ProxyAdmin"); vm.label(coreDeployment.allocationManager, "AllocationManager Proxy"); } diff --git a/test/unit/VetoableSlasher.t.sol b/test/unit/VetoableSlasher.t.sol index 317d9fc9..41fefda2 100644 --- a/test/unit/VetoableSlasher.t.sol +++ b/test/unit/VetoableSlasher.t.sol @@ -52,6 +52,7 @@ import {IVetoableSlasherTypes} from "../../src/interfaces/IVetoableSlasher.sol"; import {SocketRegistry} from "../../src/SocketRegistry.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {IVetoableSlasherErrors} from "../../src/interfaces/IVetoableSlasher.sol"; +import {MiddlewareDeployLib} from "../utils/MiddlewareDeployLib.sol"; contract VetoableSlasherTest is Test { VetoableSlasher public vetoableSlasher; @@ -155,87 +156,49 @@ contract VetoableSlasherTest is Test { ) ); - // Deploy empty proxies for all registries - stakeRegistry = StakeRegistry( - address( - new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "") - ) - ); - - blsApkRegistry = BLSApkRegistry( - address( - new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "") - ) - ); - - indexRegistry = IndexRegistry( - address( - new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "") - ) - ); - - socketRegistry = SocketRegistry( - address( - new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "") - ) - ); - - slashingRegistryCoordinatorImplementation = new SlashingRegistryCoordinator( - IStakeRegistry(address(stakeRegistry)), - IBLSApkRegistry(address(blsApkRegistry)), - IIndexRegistry(address(indexRegistry)), - ISocketRegistry(address(socketRegistry)), - IAllocationManager(coreDeployment.allocationManager), - IPauserRegistry(address(pauserRegistry)) - ); - - slashingRegistryCoordinator = SlashingRegistryCoordinator( - address( - new TransparentUpgradeableProxy( - address(slashingRegistryCoordinatorImplementation), address(proxyAdmin), "" - ) - ) - ); - - // Deploy registry implementations pointing to the coordinator - StakeRegistry stakeRegistryImplementation = new StakeRegistry( - ISlashingRegistryCoordinator(address(slashingRegistryCoordinator)), - IDelegationManager(coreDeployment.delegationManager), - IAVSDirectory(coreDeployment.avsDirectory), - IAllocationManager(coreDeployment.allocationManager) - ); - BLSApkRegistry blsApkRegistryImplementation = - new BLSApkRegistry(ISlashingRegistryCoordinator(address(slashingRegistryCoordinator))); - IndexRegistry indexRegistryImplementation = - new IndexRegistry(ISlashingRegistryCoordinator(address(slashingRegistryCoordinator))); - SocketRegistry socketRegistryImplementation = - new SocketRegistry(IRegistryCoordinator(address(slashingRegistryCoordinator))); - - // Upgrade all registry proxies - proxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(stakeRegistry))), - address(stakeRegistryImplementation) - ); - proxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(blsApkRegistry))), - address(blsApkRegistryImplementation) - ); - proxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(indexRegistry))), - address(indexRegistryImplementation) - ); - proxyAdmin.upgrade( - TransparentUpgradeableProxy(payable(address(socketRegistry))), - address(socketRegistryImplementation) - ); + MiddlewareDeployLib.MiddlewareDeployConfig memory middlewareConfig; + middlewareConfig.instantSlasher.initialOwner = proxyAdminOwner; + middlewareConfig.instantSlasher.slasher = slasher; + middlewareConfig.slashingRegistryCoordinator.initialOwner = proxyAdminOwner; + middlewareConfig.slashingRegistryCoordinator.churnApprover = churnApprover; + middlewareConfig.slashingRegistryCoordinator.ejector = ejector; + middlewareConfig.slashingRegistryCoordinator.initPausedStatus = 0; + middlewareConfig.slashingRegistryCoordinator.serviceManager = serviceManager; + middlewareConfig.socketRegistry.initialOwner = proxyAdminOwner; + middlewareConfig.indexRegistry.initialOwner = proxyAdminOwner; + middlewareConfig.stakeRegistry.initialOwner = proxyAdminOwner; + middlewareConfig.stakeRegistry.minimumStake = 1 ether; + middlewareConfig.stakeRegistry.strategyParams = 0; + middlewareConfig.stakeRegistry.delegationManager = coreDeployment.delegationManager; + middlewareConfig.stakeRegistry.avsDirectory = coreDeployment.avsDirectory; + { + IStakeRegistryTypes.StrategyParams[] memory stratParams = + new IStakeRegistryTypes.StrategyParams[](1); + stratParams[0] = + IStakeRegistryTypes.StrategyParams({strategy: mockStrategy, multiplier: 1 ether}); + middlewareConfig.stakeRegistry.strategyParamsArray = stratParams; + } + middlewareConfig.stakeRegistry.lookAheadPeriod = 0; + middlewareConfig.stakeRegistry.stakeType = IStakeRegistryTypes.StakeType(1); + middlewareConfig.blsApkRegistry.initialOwner = proxyAdminOwner; - // Initialize the SlashingRegistryCoordinator first - slashingRegistryCoordinator.initialize( - proxyAdminOwner, churnApprover, ejector, 0, serviceManager + MiddlewareDeployLib.MiddlewareDeployData memory middlewareDeployments = MiddlewareDeployLib + .deployMiddleware( + address(proxyAdmin), + coreDeployment.allocationManager, + address(pauserRegistry), + middlewareConfig ); - vm.stopPrank(); + vetoableSlasher = VetoableSlasher(middlewareDeployments.instantSlasher); + slashingRegistryCoordinator = + SlashingRegistryCoordinator(middlewareDeployments.slashingRegistryCoordinator); + stakeRegistry = StakeRegistry(middlewareDeployments.stakeRegistry); + blsApkRegistry = BLSApkRegistry(middlewareDeployments.blsApkRegistry); + indexRegistry = IndexRegistry(middlewareDeployments.indexRegistry); + socketRegistry = SocketRegistry(middlewareDeployments.socketRegistry); + vetoableSlasherImplementation = new VetoableSlasher( IAllocationManager(coreDeployment.allocationManager), ISlashingRegistryCoordinator(slashingRegistryCoordinator) @@ -413,7 +376,6 @@ contract VetoableSlasherTest is Test { } function test_fulfillSlashingRequest() public { - vm.skip(false); vm.startPrank(operatorWallet.key.addr); IDelegationManager(coreDeployment.delegationManager).registerAsOperator( address(0), 1, "metadata" diff --git a/test/utils/MiddlewareDeployLib.sol b/test/utils/MiddlewareDeployLib.sol new file mode 100644 index 00000000..6f28e0b0 --- /dev/null +++ b/test/utils/MiddlewareDeployLib.sol @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import {TransparentUpgradeableProxy} from + "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; +import {IAllocationManager} from + "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; +import {IDelegationManager} from + "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; +import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; + +import {InstantSlasher} from "../../src/slashers/InstantSlasher.sol"; +import {SlashingRegistryCoordinator} from "../../src/SlashingRegistryCoordinator.sol"; +import {SocketRegistry} from "../../src/SocketRegistry.sol"; +import {IndexRegistry} from "../../src/IndexRegistry.sol"; +import {StakeRegistry} from "../../src/StakeRegistry.sol"; +import {BLSApkRegistry} from "../../src/BLSApkRegistry.sol"; +import {IStakeRegistry, IStakeRegistryTypes} from "../../src/interfaces/IStakeRegistry.sol"; +import {IBLSApkRegistry} from "../../src/interfaces/IBLSApkRegistry.sol"; +import {IIndexRegistry} from "../../src/interfaces/IIndexRegistry.sol"; +import {ISocketRegistry} from "../../src/interfaces/ISocketRegistry.sol"; +import {ISlashingRegistryCoordinator} from "../../src/interfaces/ISlashingRegistryCoordinator.sol"; + +import {UpgradeableProxyLib} from "../unit/UpgradeableProxyLib.sol"; + +library MiddlewareDeployLib { + using UpgradeableProxyLib for address; + + struct InstantSlasherConfig { + address initialOwner; + address slasher; + } + + struct SlashingRegistryCoordinatorConfig { + address initialOwner; + address churnApprover; + address ejector; + uint256 initPausedStatus; + address serviceManager; + } + + struct SocketRegistryConfig { + address initialOwner; + } + + struct IndexRegistryConfig { + address initialOwner; + } + + struct StakeRegistryConfig { + address initialOwner; + uint256 minimumStake; + uint32 strategyParams; + address delegationManager; + address avsDirectory; + IStakeRegistryTypes.StrategyParams[] strategyParamsArray; + uint32 lookAheadPeriod; + IStakeRegistryTypes.StakeType stakeType; + } + + struct BLSApkRegistryConfig { + address initialOwner; + } + + struct MiddlewareDeployConfig { + InstantSlasherConfig instantSlasher; + SlashingRegistryCoordinatorConfig slashingRegistryCoordinator; + SocketRegistryConfig socketRegistry; + IndexRegistryConfig indexRegistry; + StakeRegistryConfig stakeRegistry; + BLSApkRegistryConfig blsApkRegistry; + } + + struct MiddlewareDeployData { + address instantSlasher; + address slashingRegistryCoordinator; + address socketRegistry; + address indexRegistry; + address stakeRegistry; + address blsApkRegistry; + } + + function deployMiddleware( + address proxyAdmin, + address allocationManager, + address pauserRegistry, + MiddlewareDeployConfig memory config + ) internal returns (MiddlewareDeployData memory result) { + result = deployEmptyProxies(proxyAdmin); + + upgradeRegistries(result, allocationManager, pauserRegistry, config); + upgradeCoordinator( + result, allocationManager, pauserRegistry, config.slashingRegistryCoordinator + ); + upgradeInstantSlasher(result, allocationManager, config.instantSlasher); + + return result; + } + + function deployEmptyProxies( + address proxyAdmin + ) internal returns (MiddlewareDeployData memory proxies) { + proxies.instantSlasher = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + proxies.slashingRegistryCoordinator = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + proxies.socketRegistry = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + proxies.indexRegistry = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + proxies.stakeRegistry = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + proxies.blsApkRegistry = UpgradeableProxyLib.setUpEmptyProxy(proxyAdmin); + return proxies; + } + + function upgradeRegistries( + MiddlewareDeployData memory deployments, + address allocationManager, + address pauserRegistry, + MiddlewareDeployConfig memory config + ) internal { + address blsApkRegistryImpl = address( + new BLSApkRegistry( + ISlashingRegistryCoordinator(deployments.slashingRegistryCoordinator) + ) + ); + UpgradeableProxyLib.upgrade(deployments.blsApkRegistry, blsApkRegistryImpl); + + address indexRegistryImpl = address( + new IndexRegistry(ISlashingRegistryCoordinator(deployments.slashingRegistryCoordinator)) + ); + UpgradeableProxyLib.upgrade(deployments.indexRegistry, indexRegistryImpl); + + address socketRegistryImpl = address( + new SocketRegistry( + ISlashingRegistryCoordinator(deployments.slashingRegistryCoordinator) + ) + ); + UpgradeableProxyLib.upgrade(deployments.socketRegistry, socketRegistryImpl); + + // StakeRegistry upgrade + address stakeRegistryImpl = address( + new StakeRegistry( + ISlashingRegistryCoordinator(deployments.slashingRegistryCoordinator), + IDelegationManager(config.stakeRegistry.delegationManager), + IAVSDirectory(config.stakeRegistry.avsDirectory), + IAllocationManager(allocationManager) + ) + ); + UpgradeableProxyLib.upgrade(deployments.stakeRegistry, stakeRegistryImpl); + } + + function upgradeCoordinator( + MiddlewareDeployData memory deployments, + address allocationManager, + address pauserRegistry, + SlashingRegistryCoordinatorConfig memory coordinatorConfig + ) internal { + address coordinatorImpl = address( + new SlashingRegistryCoordinator( + IStakeRegistry(deployments.stakeRegistry), + IBLSApkRegistry(deployments.blsApkRegistry), + IIndexRegistry(deployments.indexRegistry), + ISocketRegistry(deployments.socketRegistry), + IAllocationManager(allocationManager), + IPauserRegistry(pauserRegistry) + ) + ); + bytes memory upgradeCall = abi.encodeCall( + SlashingRegistryCoordinator.initialize, + ( + coordinatorConfig.initialOwner, + coordinatorConfig.churnApprover, + coordinatorConfig.ejector, + coordinatorConfig.initPausedStatus, + coordinatorConfig.serviceManager + ) + ); + UpgradeableProxyLib.upgradeAndCall( + deployments.slashingRegistryCoordinator, coordinatorImpl, upgradeCall + ); + } + + // Upgrade and initialize InstantSlasher with its config data + function upgradeInstantSlasher( + MiddlewareDeployData memory deployments, + address allocationManager, + InstantSlasherConfig memory slasherConfig + ) internal { + address instantSlasherImpl = address( + new InstantSlasher( + IAllocationManager(allocationManager), + ISlashingRegistryCoordinator(deployments.slashingRegistryCoordinator), + slasherConfig.slasher + ) + ); + bytes memory upgradeCall = + abi.encodeCall(InstantSlasher.initialize, (slasherConfig.slasher)); + UpgradeableProxyLib.upgradeAndCall( + deployments.instantSlasher, instantSlasherImpl, upgradeCall + ); + } +}