From 06f5bd89b429af64043efce341501807e42d116e Mon Sep 17 00:00:00 2001 From: Maurelian Date: Mon, 3 Apr 2023 13:23:37 -0400 Subject: [PATCH 1/3] fix(ctb): Update hardhat.json to fix hh deploy Missing values were causing a type error, which prevented running the basic 'npx hardhat deploy` script. --- .../contracts-bedrock/deploy-config/hardhat.json | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/deploy-config/hardhat.json b/packages/contracts-bedrock/deploy-config/hardhat.json index cb40d0bbb..fddcadf12 100644 --- a/packages/contracts-bedrock/deploy-config/hardhat.json +++ b/packages/contracts-bedrock/deploy-config/hardhat.json @@ -2,6 +2,7 @@ "finalSystemOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", "portalGuardian": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", "controller": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "proxyAdminOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", "l1StartingBlockTag": "earliest", "l1ChainID": 900, @@ -16,12 +17,22 @@ "batchSenderAddress": "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", "l2OutputOracleSubmissionInterval": 6, - "l2OutputOracleStartingTimestamp": -1, + "l2OutputOracleStartingTimestamp": 0, + "l2OutputOracleStartingBlockNumber": 0, "l2OutputOracleProposer": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", "l2OutputOracleChallenger": "0x6925B8704Ff96DEe942623d6FB5e946EF5884b63", "l2GenesisBlockBaseFeePerGas": "0x3B9ACA00", - "baseFeeVaultRecipient": "0xBcd4042DE499D14e55001CcbB24a551F3b954096", + "l2GenesisBlockGasLimit": "0x17D7840", + + "baseFeeVaultRecipient": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", + "l1FeeVaultRecipient": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", + "sequencerFeeVaultRecipient": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", + + "governanceTokenName": "Optimism", + "governanceTokenSymbol": "OP", + "governanceTokenOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", + "l1FeeVaultRecipient": "0x71bE63f3384f5fb98995898A86B02Fb2426c5788", "sequencerFeeVaultRecipient": "0xfabb0ac9d68b0b445fb7357272ff202c5651694a", From 642e1dab77cd4b818bb36674f2095dc0c55da46c Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 5 Apr 2023 12:05:10 -0400 Subject: [PATCH 2/3] feat(ctb): Add doPhase to deploy utils --- .../contracts-bedrock/src/deploy-utils.ts | 78 ++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/packages/contracts-bedrock/src/deploy-utils.ts b/packages/contracts-bedrock/src/deploy-utils.ts index 5f57a171f..9e72a9b86 100644 --- a/packages/contracts-bedrock/src/deploy-utils.ts +++ b/packages/contracts-bedrock/src/deploy-utils.ts @@ -333,6 +333,25 @@ export const isStep = async ( return (await dictator.currentStep()) === step } +/** + * Mini helper for checking if the current step is the first step in target phase. + * + * @param dictator SystemDictator contract. + * @param phase Target phase. + * @returns True if the current step is the first step in target phase. + */ +export const isStartOfPhase = async ( + dictator: ethers.Contract, + phase: number +): Promise => { + const phaseToStep = { + 1: 1, + 2: 3, + 3: 6, + } + return (await dictator.currentStep()) === phaseToStep[phase] +} + /** * Mini helper for executing a given step. * @@ -350,7 +369,8 @@ export const doStep = async (opts: { message: string checks: () => Promise }): Promise => { - if (!(await isStep(opts.SystemDictator, opts.step))) { + const isStepVal = await isStep(opts.SystemDictator, opts.step) + if (!isStepVal) { console.log(`Step already completed: ${opts.step}`) return } @@ -388,6 +408,62 @@ export const doStep = async (opts: { await opts.checks() } +/** + * Mini helper for executing a given phase. + * + * @param opts Options for executing the step. + * @param opts.isLiveDeployer True if the deployer is live. + * @param opts.SystemDictator SystemDictator contract. + * @param opts.step Step to execute. + * @param opts.message Message to print before executing the step. + * @param opts.checks Checks to perform after executing the step. + */ +export const doPhase = async (opts: { + isLiveDeployer?: boolean + SystemDictator: ethers.Contract + phase: number + message: string + checks: () => Promise +}): Promise => { + const isStart = await isStartOfPhase(opts.SystemDictator, opts.phase) + if (!isStart) { + console.log(`Start of phase ${opts.phase} already completed`) + return + } + + // Extra message to help the user understand what's going on. + console.log(opts.message) + + // Either automatically or manually execute the step. + if (opts.isLiveDeployer) { + console.log(`Executing phase ${opts.phase}...`) + await opts.SystemDictator[`phase${opts.phase}`]() + } else { + const tx = await opts.SystemDictator.populateTransaction[ + `phase${opts.phase}` + ]() + console.log(`Please execute phase ${opts.phase}...`) + console.log(`MSD address: ${opts.SystemDictator.address}`) + console.log(`JSON:`) + console.log(jsonifyTransaction(tx)) + console.log( + await getTenderlySimulationLink(opts.SystemDictator.provider, tx) + ) + } + + // Wait for the step to complete. + await awaitCondition( + async () => { + return isStartOfPhase(opts.SystemDictator, opts.phase + 1) + }, + 30000, + 1000 + ) + + // Perform post-step checks. + await opts.checks() +} + /** * Returns a direct link to a Tenderly simulation. * From 8e76fac4830292d69ce116a80b22b78f9a033bf1 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Wed, 5 Apr 2023 12:09:45 -0400 Subject: [PATCH 3/3] feat(ctb): Combine MSD step1 and step2 into phase1 --- .../contracts/deployment/SystemDictator.sol | 12 ++++++-- .../deploy/020-SystemDictatorSteps-1.ts | 30 ++++++++----------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/packages/contracts-bedrock/contracts/deployment/SystemDictator.sol b/packages/contracts-bedrock/contracts/deployment/SystemDictator.sol index 0c6f4cbe4..129dd9c08 100644 --- a/packages/contracts-bedrock/contracts/deployment/SystemDictator.sol +++ b/packages/contracts-bedrock/contracts/deployment/SystemDictator.sol @@ -215,7 +215,7 @@ contract SystemDictator is OwnableUpgradeable { /** * @notice Configures the ProxyAdmin contract. */ - function step1() external onlyOwner step(1) { + function step1() public onlyOwner step(1) { // Set the AddressManager in the ProxyAdmin. config.globalConfig.proxyAdmin.setAddressManager(config.globalConfig.addressManager); @@ -260,7 +260,7 @@ contract SystemDictator is OwnableUpgradeable { * @notice Pauses the system by shutting down the L1CrossDomainMessenger and setting the * deposit halt flag to tell the Sequencer's DTL to stop accepting deposits. */ - function step2() external onlyOwner step(2) { + function step2() public onlyOwner step(2) { // Store the address of the old L1CrossDomainMessenger implementation. We will need this // address in the case that we have to exit early. oldL1CrossDomainMessenger = config.globalConfig.addressManager.getAddress( @@ -410,6 +410,14 @@ contract SystemDictator is OwnableUpgradeable { ); } + /** + * @notice Calls the first 2 steps of the migration process. + */ + function phase1() external onlyOwner { + step1(); + step2(); + } + /** * @notice Tranfers admin ownership to the final owner. */ diff --git a/packages/contracts-bedrock/deploy/020-SystemDictatorSteps-1.ts b/packages/contracts-bedrock/deploy/020-SystemDictatorSteps-1.ts index 480af8a75..114a9901f 100644 --- a/packages/contracts-bedrock/deploy/020-SystemDictatorSteps-1.ts +++ b/packages/contracts-bedrock/deploy/020-SystemDictatorSteps-1.ts @@ -11,7 +11,7 @@ import { assertContractVariable, getContractsFromArtifacts, getDeploymentAddress, - doStep, + doPhase, jsonifyTransaction, getTenderlySimulationLink, getCastCommand, @@ -196,16 +196,23 @@ const deployFn: DeployFunction = async (hre) => { console.log(`L1ERC721Bridge already owned by MSD`) } - // Step 1 is a freebie, it doesn't impact the system. - await doStep({ + await doPhase({ isLiveDeployer, SystemDictator, - step: 1, + phase: 1, message: ` + Phase 1 includes the following steps: + Step 1 will configure the ProxyAdmin contract, you can safely execute this step at any time without impacting the functionality of the rest of the system. + + Step 2 will stop deposits and withdrawals via the L1CrossDomainMessenger and will stop the + DTL from syncing new deposits via the CTC, effectively shutting down the legacy system. Once + this step has been executed, you should immediately begin the L2 migration process. If you + need to restart the system, run exit1() followed by finalize(). `, checks: async () => { + // Step 1 checks await assertContractVariable( ProxyAdmin, 'addressManager', @@ -264,21 +271,8 @@ const deployFn: DeployFunction = async (hre) => { assert(config.systemTxMaxGas === 1_000_000) assert(ethers.utils.parseUnits('1', 'gwei').eq(config.minimumBaseFee)) assert(config.maximumBaseFee.eq(uint128Max)) - }, - }) - // Step 2 shuts down the system. - await doStep({ - isLiveDeployer, - SystemDictator, - step: 2, - message: ` - Step 2 will stop deposits and withdrawals via the L1CrossDomainMessenger and will stop the - DTL from syncing new deposits via the CTC, effectively shutting down the legacy system. Once - this step has been executed, you should immediately begin the L2 migration process. If you - need to restart the system, run exit1() followed by finalize(). - `, - checks: async () => { + // Step 2 checks const messenger = await AddressManager.getAddress( 'OVM_L1CrossDomainMessenger' )