|  | 
|  | 1 | +// SPDX-License-Identifier: BUSL-1.1 | 
|  | 2 | +pragma solidity =0.8.12; | 
|  | 3 | + | 
|  | 4 | +import "../../utils/ExistingDeploymentParser.sol"; | 
|  | 5 | + | 
|  | 6 | +/** | 
|  | 7 | + * @notice Script used for the first deployment of EigenLayer core contracts to Holesky | 
|  | 8 | + * forge script script/deploy/holesky/M2_Deploy_From_Scratch.s.sol --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv | 
|  | 9 | + * forge script script/deploy/holesky/M2_Deploy_From_Scratch.s.sol --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --broadcast -vvvv | 
|  | 10 | + *  | 
|  | 11 | + */ | 
|  | 12 | +contract M2_Deploy_Holesky_From_Scratch is ExistingDeploymentParser { | 
|  | 13 | +    function run() external virtual { | 
|  | 14 | +        _parseInitialDeploymentParams("script/configs/holesky/M2_deploy_from_scratch.holesky.config.json"); | 
|  | 15 | + | 
|  | 16 | +        // START RECORDING TRANSACTIONS FOR DEPLOYMENT | 
|  | 17 | +        vm.startBroadcast(); | 
|  | 18 | + | 
|  | 19 | +        emit log_named_address("Deployer Address", msg.sender); | 
|  | 20 | + | 
|  | 21 | +        _deployFromScratch(); | 
|  | 22 | + | 
|  | 23 | +        // STOP RECORDING TRANSACTIONS FOR DEPLOYMENT | 
|  | 24 | +        vm.stopBroadcast(); | 
|  | 25 | + | 
|  | 26 | +        // Sanity Checks | 
|  | 27 | +        _verifyContractPointers(); | 
|  | 28 | +        _verifyImplementations(); | 
|  | 29 | +        _verifyContractsInitialized({isInitialDeployment: true}); | 
|  | 30 | +        _verifyInitializationParams(); | 
|  | 31 | + | 
|  | 32 | +        logAndOutputContractAddresses("script/output/holesky/M2_deploy_from_scratch.holesky.config.json"); | 
|  | 33 | +    } | 
|  | 34 | + | 
|  | 35 | +    /** | 
|  | 36 | +     * @notice Deploy EigenLayer contracts from scratch for Holesky | 
|  | 37 | +     */ | 
|  | 38 | +    function _deployFromScratch() internal { | 
|  | 39 | +        // Deploy ProxyAdmin, later set admins for all proxies to be executorMultisig | 
|  | 40 | +        eigenLayerProxyAdmin = new ProxyAdmin(); | 
|  | 41 | + | 
|  | 42 | +        // Set multisigs as pausers, executorMultisig as unpauser | 
|  | 43 | +        address[] memory pausers = new address[](3); | 
|  | 44 | +        pausers[0] = executorMultisig; | 
|  | 45 | +        pausers[1] = operationsMultisig; | 
|  | 46 | +        pausers[2] = pauserMultisig; | 
|  | 47 | +        address unpauser = executorMultisig; | 
|  | 48 | +        eigenLayerPauserReg = new PauserRegistry(pausers, unpauser); | 
|  | 49 | + | 
|  | 50 | +        /** | 
|  | 51 | +         * First, deploy upgradeable proxy contracts that **will point** to the implementations. Since the implementation contracts are | 
|  | 52 | +         * not yet deployed, we give these proxies an empty contract as the initial implementation, to act as if they have no code. | 
|  | 53 | +         */ | 
|  | 54 | +        emptyContract = new EmptyContract(); | 
|  | 55 | +        avsDirectory = AVSDirectory( | 
|  | 56 | +            address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) | 
|  | 57 | +        ); | 
|  | 58 | +        delegationManager = DelegationManager( | 
|  | 59 | +            address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) | 
|  | 60 | +        ); | 
|  | 61 | +        strategyManager = StrategyManager( | 
|  | 62 | +            address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) | 
|  | 63 | +        ); | 
|  | 64 | +        slasher = Slasher( | 
|  | 65 | +            address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) | 
|  | 66 | +        ); | 
|  | 67 | +        eigenPodManager = EigenPodManager( | 
|  | 68 | +            address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) | 
|  | 69 | +        ); | 
|  | 70 | +        delayedWithdrawalRouter = DelayedWithdrawalRouter( | 
|  | 71 | +            address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) | 
|  | 72 | +        ); | 
|  | 73 | + | 
|  | 74 | +        // Deploy EigenPod Contracts | 
|  | 75 | +        eigenPodImplementation = new EigenPod( | 
|  | 76 | +            IETHPOSDeposit(ETHPOSDepositAddress), | 
|  | 77 | +            delayedWithdrawalRouter, | 
|  | 78 | +            eigenPodManager, | 
|  | 79 | +            EIGENPOD_MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, | 
|  | 80 | +            EIGENPOD_GENESIS_TIME | 
|  | 81 | +        ); | 
|  | 82 | + | 
|  | 83 | +        eigenPodBeacon = new UpgradeableBeacon(address(eigenPodImplementation)); | 
|  | 84 | +        avsDirectoryImplementation = new AVSDirectory(delegationManager); | 
|  | 85 | +        delegationManagerImplementation = new DelegationManager(strategyManager, slasher, eigenPodManager); | 
|  | 86 | +        strategyManagerImplementation = new StrategyManager(delegationManager, eigenPodManager, slasher); | 
|  | 87 | +        slasherImplementation = new Slasher(strategyManager, delegationManager); | 
|  | 88 | +        eigenPodManagerImplementation = new EigenPodManager( | 
|  | 89 | +            IETHPOSDeposit(ETHPOSDepositAddress), | 
|  | 90 | +            eigenPodBeacon, | 
|  | 91 | +            strategyManager, | 
|  | 92 | +            slasher, | 
|  | 93 | +            delegationManager | 
|  | 94 | +        ); | 
|  | 95 | +        delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter(eigenPodManager); | 
|  | 96 | + | 
|  | 97 | +        // Third, upgrade the proxy contracts to point to the implementations | 
|  | 98 | +        IStrategy[] memory initializeStrategiesToSetDelayBlocks = new IStrategy[](0); | 
|  | 99 | +        uint256[] memory initializeWithdrawalDelayBlocks = new uint256[](0); | 
|  | 100 | +        // AVSDirectory | 
|  | 101 | +        eigenLayerProxyAdmin.upgradeAndCall( | 
|  | 102 | +            TransparentUpgradeableProxy(payable(address(avsDirectory))), | 
|  | 103 | +            address(avsDirectoryImplementation), | 
|  | 104 | +            abi.encodeWithSelector( | 
|  | 105 | +                AVSDirectory.initialize.selector, | 
|  | 106 | +                executorMultisig, // initialOwner | 
|  | 107 | +                eigenLayerPauserReg, | 
|  | 108 | +                AVS_DIRECTORY_INIT_PAUSED_STATUS | 
|  | 109 | +            ) | 
|  | 110 | +        ); | 
|  | 111 | +        // DelegationManager | 
|  | 112 | +        eigenLayerProxyAdmin.upgradeAndCall( | 
|  | 113 | +            TransparentUpgradeableProxy(payable(address(delegationManager))), | 
|  | 114 | +            address(delegationManagerImplementation), | 
|  | 115 | +            abi.encodeWithSelector( | 
|  | 116 | +                DelegationManager.initialize.selector, | 
|  | 117 | +                executorMultisig, // initialOwner | 
|  | 118 | +                eigenLayerPauserReg, | 
|  | 119 | +                DELEGATION_MANAGER_INIT_PAUSED_STATUS, | 
|  | 120 | +                DELEGATION_MANAGER_MIN_WITHDRAWAL_DELAY_BLOCKS, | 
|  | 121 | +                initializeStrategiesToSetDelayBlocks, | 
|  | 122 | +                initializeWithdrawalDelayBlocks | 
|  | 123 | +            ) | 
|  | 124 | +        ); | 
|  | 125 | +        // StrategyManager | 
|  | 126 | +        eigenLayerProxyAdmin.upgradeAndCall( | 
|  | 127 | +            TransparentUpgradeableProxy(payable(address(strategyManager))), | 
|  | 128 | +            address(strategyManagerImplementation), | 
|  | 129 | +            abi.encodeWithSelector( | 
|  | 130 | +                StrategyManager.initialize.selector, | 
|  | 131 | +                executorMultisig, //initialOwner | 
|  | 132 | +                STRATEGY_MANAGER_WHITELISTER, //initial whitelister | 
|  | 133 | +                eigenLayerPauserReg, | 
|  | 134 | +                STRATEGY_MANAGER_INIT_PAUSED_STATUS | 
|  | 135 | +            ) | 
|  | 136 | +        ); | 
|  | 137 | +        // Slasher | 
|  | 138 | +        eigenLayerProxyAdmin.upgradeAndCall( | 
|  | 139 | +            TransparentUpgradeableProxy(payable(address(slasher))), | 
|  | 140 | +            address(slasherImplementation), | 
|  | 141 | +            abi.encodeWithSelector( | 
|  | 142 | +                Slasher.initialize.selector, | 
|  | 143 | +                executorMultisig, | 
|  | 144 | +                eigenLayerPauserReg, | 
|  | 145 | +                SLASHER_INIT_PAUSED_STATUS | 
|  | 146 | +            ) | 
|  | 147 | +        ); | 
|  | 148 | +        // EigenPodManager | 
|  | 149 | +        eigenLayerProxyAdmin.upgradeAndCall( | 
|  | 150 | +            TransparentUpgradeableProxy(payable(address(eigenPodManager))), | 
|  | 151 | +            address(eigenPodManagerImplementation), | 
|  | 152 | +            abi.encodeWithSelector( | 
|  | 153 | +                EigenPodManager.initialize.selector, | 
|  | 154 | +                beaconOracle, | 
|  | 155 | +                msg.sender, // initialOwner is msg.sender for now to set forktimestamp later | 
|  | 156 | +                eigenLayerPauserReg, | 
|  | 157 | +                EIGENPOD_MANAGER_INIT_PAUSED_STATUS | 
|  | 158 | +            ) | 
|  | 159 | +        ); | 
|  | 160 | +        // Delayed Withdrawal Router | 
|  | 161 | +        eigenLayerProxyAdmin.upgradeAndCall( | 
|  | 162 | +            TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), | 
|  | 163 | +            address(delayedWithdrawalRouterImplementation), | 
|  | 164 | +            abi.encodeWithSelector( | 
|  | 165 | +                DelayedWithdrawalRouter.initialize.selector, | 
|  | 166 | +                executorMultisig, // initialOwner | 
|  | 167 | +                eigenLayerPauserReg, | 
|  | 168 | +                DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS, | 
|  | 169 | +                DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS | 
|  | 170 | +            ) | 
|  | 171 | +        ); | 
|  | 172 | + | 
|  | 173 | +        // Deploy Strategies | 
|  | 174 | +        baseStrategyImplementation = new StrategyBaseTVLLimits(strategyManager); | 
|  | 175 | +        uint256 numStrategiesToDeploy = strategiesToDeploy.length; | 
|  | 176 | +        for (uint256 i = 0; i < numStrategiesToDeploy; i++) { | 
|  | 177 | +            StrategyUnderlyingTokenConfig memory strategyConfig = strategiesToDeploy[i]; | 
|  | 178 | + | 
|  | 179 | +            // Deploy and upgrade strategy | 
|  | 180 | +            StrategyBaseTVLLimits strategy = StrategyBaseTVLLimits( | 
|  | 181 | +                address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) | 
|  | 182 | +            ); | 
|  | 183 | +            eigenLayerProxyAdmin.upgradeAndCall( | 
|  | 184 | +                TransparentUpgradeableProxy(payable(address(strategy))), | 
|  | 185 | +                address(baseStrategyImplementation), | 
|  | 186 | +                abi.encodeWithSelector( | 
|  | 187 | +                    StrategyBaseTVLLimits.initialize.selector, | 
|  | 188 | +                    STRATEGY_MAX_PER_DEPOSIT, | 
|  | 189 | +                    STRATEGY_MAX_TOTAL_DEPOSITS, | 
|  | 190 | +                    IERC20(strategyConfig.tokenAddress), | 
|  | 191 | +                    eigenLayerPauserReg | 
|  | 192 | +                ) | 
|  | 193 | +            ); | 
|  | 194 | + | 
|  | 195 | +            deployedStrategyArray.push(strategy); | 
|  | 196 | +        } | 
|  | 197 | + | 
|  | 198 | +        // Fork timestamp config | 
|  | 199 | +        eigenPodManager.setDenebForkTimestamp(EIGENPOD_MANAGER_DENEB_FORK_TIMESTAMP); | 
|  | 200 | + | 
|  | 201 | +        // Transfer ownership | 
|  | 202 | +        eigenLayerProxyAdmin.transferOwnership(executorMultisig); | 
|  | 203 | +        eigenPodManager.transferOwnership(executorMultisig); | 
|  | 204 | +        eigenPodBeacon.transferOwnership(executorMultisig); | 
|  | 205 | +    } | 
|  | 206 | +} | 
0 commit comments