-
Notifications
You must be signed in to change notification settings - Fork 449
feat: m2 mainnet upgrade script #480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d074879
944abf0
0491a77
9b7a0c3
02f7aff
888d3c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
{ | ||
"chainInfo": { | ||
"chainId": 1 | ||
}, | ||
"multisig_addresses": { | ||
"communityMultisig": "0xFEA47018D632A77bA579846c840d5706705Dc598", | ||
"executorMultisig": "0x369e6F597e22EaB55fFb173C6d9cD234BD699111", | ||
"operationsMultisig": "0xBE1685C81aA44FF9FB319dD389addd9374383e90", | ||
"pauserMultisig": "0x5050389572f2d220ad927CcbeA0D406831012390", | ||
"timelock": "0xA6Db1A8C5a981d1536266D2a393c5F8dDb210EAF" | ||
}, | ||
"strategies": { | ||
"numStrategies": 0, | ||
"MAX_PER_DEPOSIT": 115792089237316195423570985008687907853269984665640564039457584007913129639935, | ||
"MAX_TOTAL_DEPOSITS": 115792089237316195423570985008687907853269984665640564039457584007913129639935, | ||
"strategiesToDeploy": [] | ||
}, | ||
"strategyManager": { | ||
"init_strategy_whitelister": "0xBE1685C81aA44FF9FB319dD389addd9374383e90", | ||
"init_paused_status": 1 | ||
}, | ||
"delegationManager": { | ||
"init_paused_status": 0, | ||
"init_minWithdrawalDelayBlocks": 50400 | ||
}, | ||
"avsDirectory": { | ||
"init_paused_status": 0 | ||
}, | ||
"slasher": { | ||
"init_paused_status": 115792089237316195423570985008687907853269984665640564039457584007913129639935 | ||
}, | ||
"eigenPod": { | ||
"MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR": 32000000000, | ||
"GENESIS_TIME": 1606824023 | ||
}, | ||
"eigenPodManager": { | ||
"init_paused_status": 0, | ||
"deneb_fork_timestamp": "1710338135" | ||
}, | ||
"delayedWithdrawalRouter": { | ||
"init_paused_status": 0, | ||
"init_withdrawalDelayBlocks": 50400 | ||
}, | ||
"ethPOSDepositAddress": "0x00000000219ab540356cBB839Cbe05303d7705Fa", | ||
"beaconOracleAddress": "0x343907185b71aDF0eBa9567538314396aa985442" | ||
ChaoticWalrus marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,306 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity =0.8.12; | ||
|
||
import "../../utils/ExistingDeploymentParser.sol"; | ||
import "../../utils/TimelockEncoding.sol"; | ||
import "../../utils/Multisend.sol"; | ||
|
||
/** | ||
* @notice Script used for the first deployment of EigenLayer core contracts to Holesky | ||
* anvil --fork-url $RPC_MAINNET | ||
* forge script script/deploy/mainnet/M2_Mainnet_Upgrade.s.sol:M2_Mainnet_Upgrade --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv | ||
* | ||
* forge script script/deploy/mainnet/M2_Mainnet_Upgrade.s.sol:M2_Mainnet_Upgrade --rpc-url $RPC_MAINNET --private-key $PRIVATE_KEY --broadcast -vvvv | ||
* | ||
*/ | ||
contract M2_Mainnet_Upgrade is ExistingDeploymentParser { | ||
function run() external virtual { | ||
_parseDeployedContracts("script/output/mainnet/M1_deployment_mainnet_2023_6_9.json"); | ||
_parseInitialDeploymentParams("script/configs/mainnet/M2_mainnet_upgrade.config.json"); | ||
|
||
// START RECORDING TRANSACTIONS FOR DEPLOYMENT | ||
vm.startBroadcast(); | ||
|
||
emit log_named_address("Deployer Address", msg.sender); | ||
|
||
_deployImplementationContracts(); | ||
|
||
// STOP RECORDING TRANSACTIONS FOR DEPLOYMENT | ||
vm.stopBroadcast(); | ||
|
||
// Simulate upgrade of contracts to new implementations | ||
_simulateUpgrade(); | ||
|
||
// Sanity Checks | ||
_verifyContractPointers(); | ||
ChaoticWalrus marked this conversation as resolved.
Show resolved
Hide resolved
|
||
_verifyImplementations(); | ||
_verifyContractsInitialized({isInitialDeployment: true}); | ||
_verifyInitializationParams(); | ||
|
||
logAndOutputContractAddresses("script/output/mainnet/M2_mainnet_upgrade.output.json"); | ||
} | ||
|
||
/** | ||
* @notice Deploy EigenLayer contracts from scratch for Holesky | ||
*/ | ||
function _deployImplementationContracts() internal { | ||
// 1. Deploy New TUPS | ||
avsDirectoryImplementation = new AVSDirectory(delegationManager); | ||
avsDirectory = AVSDirectory( | ||
address( | ||
new TransparentUpgradeableProxy( | ||
address(avsDirectoryImplementation), | ||
address(eigenLayerProxyAdmin), | ||
abi.encodeWithSelector( | ||
AVSDirectory.initialize.selector, | ||
executorMultisig, // initialOwner | ||
eigenLayerPauserReg, | ||
AVS_DIRECTORY_INIT_PAUSED_STATUS | ||
) | ||
) | ||
) | ||
); | ||
|
||
// 2. Deploy Implementations | ||
eigenPodImplementation = new EigenPod( | ||
IETHPOSDeposit(ETHPOSDepositAddress), | ||
delayedWithdrawalRouter, | ||
eigenPodManager, | ||
EIGENPOD_MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR, | ||
EIGENPOD_GENESIS_TIME | ||
); | ||
delegationManagerImplementation = new DelegationManager(strategyManager, slasher, eigenPodManager); | ||
strategyManagerImplementation = new StrategyManager(delegationManager, eigenPodManager, slasher); | ||
slasherImplementation = new Slasher(strategyManager, delegationManager); | ||
eigenPodManagerImplementation = new EigenPodManager( | ||
IETHPOSDeposit(ETHPOSDepositAddress), | ||
eigenPodBeacon, | ||
strategyManager, | ||
slasher, | ||
delegationManager | ||
); | ||
delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter(eigenPodManager); | ||
} | ||
|
||
function _simulateUpgrade() internal { | ||
wadealexc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
vm.startPrank(executorMultisig); | ||
|
||
// First, upgrade the proxy contracts to point to the implementations | ||
// AVSDirectory | ||
// eigenLayerProxyAdmin.upgrade( | ||
// TransparentUpgradeableProxy(payable(address(avsDirectory))), | ||
// address(avsDirectoryImplementation) | ||
// ); | ||
// DelegationManager | ||
eigenLayerProxyAdmin.upgrade( | ||
TransparentUpgradeableProxy(payable(address(delegationManager))), | ||
address(delegationManagerImplementation) | ||
); | ||
// StrategyManager | ||
eigenLayerProxyAdmin.upgrade( | ||
TransparentUpgradeableProxy(payable(address(strategyManager))), | ||
address(strategyManagerImplementation) | ||
); | ||
// Slasher | ||
eigenLayerProxyAdmin.upgrade( | ||
TransparentUpgradeableProxy(payable(address(slasher))), | ||
address(slasherImplementation) | ||
); | ||
// EigenPodManager | ||
eigenLayerProxyAdmin.upgrade( | ||
TransparentUpgradeableProxy(payable(address(eigenPodManager))), | ||
address(eigenPodManagerImplementation) | ||
); | ||
// Delayed Withdrawal Router | ||
eigenLayerProxyAdmin.upgrade( | ||
TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), | ||
address(delayedWithdrawalRouterImplementation) | ||
); | ||
|
||
// Second, configure additional settings and paused statuses | ||
delegationManager.setMinWithdrawalDelayBlocks(DELEGATION_MANAGER_MIN_WITHDRAWAL_DELAY_BLOCKS); | ||
delegationManager.unpause(0); | ||
eigenPodManager.unpause(0); | ||
|
||
eigenPodManager.setDenebForkTimestamp(EIGENPOD_MANAGER_DENEB_FORK_TIMESTAMP); | ||
eigenPodManager.updateBeaconChainOracle(beaconOracle); | ||
eigenPodBeacon.upgradeTo(address(eigenPodImplementation)); | ||
|
||
vm.stopPrank(); | ||
} | ||
} | ||
|
||
// forge t --mt test_queueUpgrade --fork-url $RPC_MAINNET -vvvv | ||
contract Queue_M2_Upgrade is M2_Mainnet_Upgrade, TimelockEncoding { | ||
Vm cheats = Vm(HEVM_ADDRESS); | ||
|
||
// Thurs Apr 04 2024 12:00:00 GMT-0700 (Pacific Daylight Time) | ||
uint256 timelockEta = 1712214000; | ||
|
||
function test_queueUpgrade() external { | ||
_parseDeployedContracts("script/output/mainnet/M1_deployment_mainnet_2023_6_9.json"); | ||
_parseInitialDeploymentParams("script/configs/mainnet/M2_mainnet_upgrade.config.json"); | ||
|
||
// TODO: fill in correct addresses | ||
// simulate deploying contracts | ||
_deployImplementationContracts(); | ||
|
||
Tx[] memory txs = new Tx[](11); | ||
// upgrade the DelegationManager, Slasher, StrategyManager, DelayedWithdrawalRouter, EigenPodManager, & EigenPod contracts | ||
txs[0] = Tx( | ||
address(eigenLayerProxyAdmin), | ||
0, | ||
abi.encodeWithSelector( | ||
ProxyAdmin.upgrade.selector, | ||
TransparentUpgradeableProxy(payable(address(delegationManager))), | ||
delegationManagerImplementation | ||
) | ||
); | ||
|
||
txs[1] = Tx( | ||
address(eigenLayerProxyAdmin), | ||
0, | ||
abi.encodeWithSelector( | ||
ProxyAdmin.upgrade.selector, | ||
TransparentUpgradeableProxy(payable(address(slasher))), | ||
slasherImplementation | ||
) | ||
); | ||
|
||
txs[2] = Tx( | ||
address(eigenLayerProxyAdmin), | ||
0, | ||
abi.encodeWithSelector( | ||
ProxyAdmin.upgrade.selector, | ||
TransparentUpgradeableProxy(payable(address(strategyManager))), | ||
strategyManagerImplementation | ||
) | ||
); | ||
|
||
txs[3] = Tx( | ||
address(eigenLayerProxyAdmin), | ||
0, | ||
abi.encodeWithSelector( | ||
ProxyAdmin.upgrade.selector, | ||
TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), | ||
delayedWithdrawalRouterImplementation | ||
) | ||
); | ||
|
||
txs[4] = Tx( | ||
address(eigenLayerProxyAdmin), | ||
0, | ||
abi.encodeWithSelector( | ||
ProxyAdmin.upgrade.selector, | ||
TransparentUpgradeableProxy(payable(address(eigenPodManager))), | ||
eigenPodManagerImplementation | ||
) | ||
); | ||
|
||
txs[5] = Tx( | ||
address(eigenPodBeacon), | ||
0, | ||
abi.encodeWithSelector( | ||
UpgradeableBeacon.upgradeTo.selector, | ||
eigenPodImplementation | ||
) | ||
); | ||
|
||
// set the min withdrawal delay blocks on the DelegationManager | ||
txs[6] = Tx( | ||
address(delegationManager), | ||
0, // value | ||
abi.encodeWithSelector(DelegationManager.setMinWithdrawalDelayBlocks.selector, DELEGATION_MANAGER_MIN_WITHDRAWAL_DELAY_BLOCKS) | ||
); | ||
|
||
// set beacon chain oracle on EigenPodManager | ||
txs[7] = Tx( | ||
address(eigenPodManager), | ||
0, // value | ||
abi.encodeWithSelector(EigenPodManager.updateBeaconChainOracle.selector, beaconOracle) | ||
); | ||
|
||
// set Deneb fork timestamp on EigenPodManager | ||
txs[8] = Tx( | ||
address(eigenPodManager), | ||
0, // value | ||
abi.encodeWithSelector(EigenPodManager.setDenebForkTimestamp.selector, EIGENPOD_MANAGER_DENEB_FORK_TIMESTAMP) | ||
); | ||
|
||
// unpause everything on DelegationManager | ||
txs[9] = Tx( | ||
address(delegationManager), | ||
0, // value | ||
abi.encodeWithSelector(Pausable.unpause.selector, 0) | ||
); | ||
|
||
// unpause everything on EigenPodManager | ||
txs[10] = Tx( | ||
address(eigenPodManager), | ||
0, // value | ||
abi.encodeWithSelector(Pausable.unpause.selector, 0) | ||
); | ||
|
||
bytes memory calldata_to_multisend_contract = abi.encodeWithSelector(MultiSendCallOnly.multiSend.selector, encodeMultisendTxs(txs)); | ||
emit log_named_bytes("calldata_to_multisend_contract", calldata_to_multisend_contract); | ||
|
||
bytes memory final_calldata_to_executor_multisig = encodeForExecutor({ | ||
// call to executor will be from the timelock | ||
from: timelock, | ||
// performing many operations at the same time | ||
to: multiSendCallOnly, | ||
// value to send in tx | ||
value: 0, | ||
// calldata for the operation | ||
data: calldata_to_multisend_contract, | ||
// operation type (for performing many operations at the same time) | ||
operation: ISafe.Operation.DelegateCall | ||
}); | ||
|
||
(bytes memory calldata_to_timelock_queuing_action, bytes memory calldata_to_timelock_executing_action) = encodeForTimelock({ | ||
// address to be called from the timelock | ||
to: executorMultisig, | ||
// value to send in tx | ||
value: 0, | ||
// calldata for the operation | ||
data: final_calldata_to_executor_multisig, | ||
// time at which the tx will become executable | ||
timelockEta: timelockEta | ||
|
||
}); | ||
|
||
bytes32 expectedTxHash = getTxHash({ | ||
target: executorMultisig, | ||
_value: 0, | ||
_data: final_calldata_to_executor_multisig, | ||
eta: timelockEta | ||
}); | ||
emit log_named_bytes32("expectedTxHash", expectedTxHash); | ||
|
||
cheats.prank(operationsMultisig); | ||
(bool success, ) = timelock.call(calldata_to_timelock_queuing_action); | ||
require(success, "call to timelock queuing action failed"); | ||
|
||
require(ITimelock(timelock).queuedTransactions(expectedTxHash), "expectedTxHash not queued"); | ||
|
||
// test performing the upgrade | ||
cheats.warp(timelockEta); | ||
cheats.prank(operationsMultisig); | ||
(success, ) = timelock.call(calldata_to_timelock_executing_action); | ||
require(success, "call to timelock executing action failed"); | ||
|
||
// Check correctness after upgrade | ||
_verifyContractPointers(); | ||
_verifyImplementations(); | ||
_verifyContractsInitialized({isInitialDeployment: true}); | ||
_verifyInitializationParams(); | ||
} | ||
|
||
function getTxHash(address target, uint256 _value, bytes memory _data, uint256 eta) public pure returns (bytes32) { | ||
// empty bytes | ||
bytes memory signature; | ||
bytes32 txHash = keccak256(abi.encode(target, _value, signature, _data, eta)); | ||
return txHash; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,9 @@ | ||
{ | ||
"addresses": { | ||
"avsDirectory": "0x0000000000000000000000000000000000000000", | ||
"avsDirectoryImplementation": "0x0000000000000000000000000000000000000000", | ||
"baseStrategyImplementation": "0xdfdA04f980bE6A64E3607c95Ca26012Ab9aA46d3", | ||
"beaconOracleAddress": "0x0000000000000000000000000000000000000000", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be non-zero? I get that the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yes I added this because the |
||
"delayedWithdrawalRouter": "0x7Fe7E9CC0F274d2435AD5d56D5fa73E47F6A23D8", | ||
"delayedWithdrawalRouterImplementation": "0x44Bcb0E01CD0C5060D4Bb1A07b42580EF983E2AF", | ||
"delegation": "0x39053D51B77DC0d36036Fc1fCc8Cb819df8Ef37A", | ||
|
Uh oh!
There was an error while loading. Please reload this page.