Commit fe163071 authored by Kelvin Fichter's avatar Kelvin Fichter

feat(ctb): add MigrationSystemDictator checks

Adds checks for the MigrationSystemDictator steps.
parent 9dad975a
......@@ -46,6 +46,22 @@ const deployFn: DeployFunction = async (hre) => {
}
}
if (
hre.deployConfig.l2OutputOracleGenesisL2Output === ethers.constants.HashZero
) {
if (hre.network.config.live === false) {
console.log(`WARNING!!!`)
console.log(`WARNING!!!`)
console.log(`WARNING!!!`)
console.log(`WARNING!!! A genesis L2 output was not provided.`)
console.log(
`WARNING!!! Make sure you are ONLY doing this on a test network.`
)
} else {
throw new Error(`must specify the finalSystemOwner on live networks`)
}
}
const config = await makeDictatorConfig(hre, controller, finalOwner, false)
await deployAndVerifyAndThen({
hre,
......
import assert from 'assert'
import { ethers } from 'ethers'
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { awaitCondition } from '@eth-optimism/core-utils'
import '@eth-optimism/hardhat-deploy-config'
import 'hardhat-deploy'
import { awaitCondition } from '@eth-optimism/core-utils'
import '@nomiclabs/hardhat-ethers'
import { getContractFromArtifact } from '../src/deploy-utils'
import {
assertContractVariable,
getContractsFromArtifacts,
getDeploymentAddress,
} from '../src/deploy-utils'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
let isLiveDeployer = false
let controller = hre.deployConfig.controller
if (controller === ethers.constants.AddressZero) {
if (hre.network.config.live === false) {
console.log(`WARNING!!!`)
console.log(`WARNING!!!`)
console.log(`WARNING!!!`)
console.log(`WARNING!!! A controller address was not provided.`)
console.log(
`WARNING!!! Make sure you are ONLY doing this on a test network.`
)
controller = deployer
isLiveDeployer = true
} else {
throw new Error(
`controller address MUST NOT be the deployer on live networks`
)
}
if (hre.deployConfig.controller === deployer) {
console.log('using a live deployer')
isLiveDeployer = true
}
const MigrationSystemDictator = await getContractFromArtifact(
hre,
'MigrationSystemDictator',
// Set up required contract references.
const [
MigrationSystemDictator,
ProxyAdmin,
AddressManager,
L1CrossDomainMessenger,
L1StandardBridgeProxy,
L1StandardBridgeProxyWithSigner,
L1StandardBridge,
L2OutputOracle,
OptimismPortal,
OptimismMintableERC20Factory,
L1ERC721Bridge,
] = await getContractsFromArtifacts(hre, [
{
name: 'MigrationSystemDictator',
signerOrProvider: deployer,
}
)
},
{
name: 'ProxyAdmin',
signerOrProvider: deployer,
},
{
name: 'Lib_AddressManager',
signerOrProvider: deployer,
},
{
name: 'Proxy__OVM_L1CrossDomainMessenger',
iface: 'L1CrossDomainMessenger',
signerOrProvider: deployer,
},
{
name: 'Proxy__OVM_L1StandardBridge',
},
{
name: 'Proxy__OVM_L1StandardBridge',
signerOrProvider: deployer,
},
{
name: 'Proxy__OVM_L1StandardBridge',
iface: 'L1StandardBridge',
signerOrProvider: deployer,
},
{
name: 'L2OutputOracleProxy',
iface: 'L2OutputOracle',
signerOrProvider: deployer,
},
{
name: 'OptimismPortalProxy',
iface: 'OptimismPortal',
signerOrProvider: deployer,
},
{
name: 'OptimismMintableERC20FactoryProxy',
iface: 'OptimismMintableERC20Factory',
signerOrProvider: deployer,
},
{
name: 'L1ERC721BridgeProxy',
iface: 'L1ERC721Bridge',
signerOrProvider: deployer,
},
])
// Transfer ownership of the ProxyAdmin to the MigrationSystemDictator
const ProxyAdmin = await getContractFromArtifact(hre, 'ProxyAdmin', {
signerOrProvider: deployer,
})
// Transfer ownership of the ProxyAdmin to the MigrationSystemDictator.
if ((await ProxyAdmin.owner()) !== MigrationSystemDictator.address) {
console.log(
`Transferring proxy admin ownership to the MigrationSystemDictator`
)
console.log(`Setting ProxyAdmin owner to MSD`)
await ProxyAdmin.transferOwnership(MigrationSystemDictator.address)
} else {
console.log(`Proxy admin already owned by the MigrationSystemDictator`)
console.log(`Proxy admin already owned by MSD`)
}
// Transfer ownership of the AddressManager to MigrationSystemDictator.
const AddressManager = await getContractFromArtifact(
hre,
'Lib_AddressManager',
{
signerOrProvider: deployer,
}
)
if ((await AddressManager.owner()) !== MigrationSystemDictator.address) {
if (isLiveDeployer) {
console.log(
`Transferring ownership of AddressManager to the MigrationSystemDictator...`
)
console.log(`Setting AddressManager owner to MSD`)
await AddressManager.transferOwnership(MigrationSystemDictator.address)
} else {
console.log(
`Please transfer ownership of the AddressManager to the MigrationSystemDictator located at: ${MigrationSystemDictator.address}`
)
console.log(`Please transfer AddressManager owner to MSD`)
console.log(`MSD address: ${MigrationSystemDictator.address}`)
}
// Wait for the ownership transfer to complete.
await awaitCondition(async () => {
const owner = await AddressManager.owner()
return owner === MigrationSystemDictator.address
......@@ -78,88 +115,245 @@ const deployFn: DeployFunction = async (hre) => {
}
// Transfer ownership of the L1CrossDomainMessenger to MigrationSystemDictator.
const L1CrossDomainMessenger = await getContractFromArtifact(
hre,
'Proxy__OVM_L1CrossDomainMessenger',
{
iface: 'L1CrossDomainMessenger',
signerOrProvider: deployer,
}
)
if (
(await L1CrossDomainMessenger.owner()) !== MigrationSystemDictator.address
) {
if (isLiveDeployer) {
console.log(
`Transferring ownership of L1CrossDomainMessenger to the MigrationSystemDictator...`
)
console.log(`Setting L1CrossDomainMessenger owner to MSD`)
await L1CrossDomainMessenger.transferOwnership(
MigrationSystemDictator.address
)
} else {
console.log(
`Please transfer ownership of the L1CrossDomainMessenger to the MigrationSystemDictator located at: ${MigrationSystemDictator.address}`
)
console.log(`Please transfer L1CrossDomainMessenger owner to MSD`)
console.log(`MSD address: ${MigrationSystemDictator.address}`)
}
// Wait for the ownership transfer to complete.
await awaitCondition(async () => {
const owner = await L1CrossDomainMessenger.owner()
return owner === MigrationSystemDictator.address
})
} else {
console.log(
`L1CrossDomainMessenger already owned by the MigrationSystemDictator`
)
console.log(`L1CrossDomainMessenger already owned by MSD`)
}
// Transfer ownership of the L1StandardBridge (proxy) to MigrationSystemDictator.
const L1StandardBridge = await getContractFromArtifact(
hre,
'Proxy__OVM_L1StandardBridge'
)
const getOwnerOpts = {
from: ethers.constants.AddressZero,
}
if (
(await L1StandardBridge.callStatic.getOwner(getOwnerOpts)) !==
MigrationSystemDictator.address
(await L1StandardBridgeProxy.callStatic.getOwner({
from: ethers.constants.AddressZero,
})) !== MigrationSystemDictator.address
) {
if (isLiveDeployer) {
console.log(
`Transferring ownership of L1StandardBridge to the MigrationSystemDictator...`
)
const L1StandardBridgeWithSigner = await getContractFromArtifact(
hre,
'Proxy__OVM_L1StandardBridge',
{
signerOrProvider: deployer,
}
console.log(`Setting L1StandardBridge owner to MSD`)
await L1StandardBridgeProxyWithSigner.setOwner(
MigrationSystemDictator.address
)
await L1StandardBridgeWithSigner.setOwner(MigrationSystemDictator.address)
} else {
console.log(
`Please transfer ownership of the L1StandardBridge (proxy) to the MigrationSystemDictator located at: ${MigrationSystemDictator.address}`
)
console.log(`Please transfer L1StandardBridge (proxy) owner to MSD`)
console.log(`MSD address: ${MigrationSystemDictator.address}`)
}
// Wait for the ownership transfer to complete.
await awaitCondition(async () => {
const owner = await L1StandardBridge.callStatic.getOwner(getOwnerOpts)
const owner = await L1StandardBridgeProxy.callStatic.getOwner({
from: ethers.constants.AddressZero,
})
return owner === MigrationSystemDictator.address
})
} else {
console.log(`L1StandardBridge already owned by the MigrationSystemDictator`)
console.log(`L1StandardBridge already owned by MSD`)
}
const checks = {
1: async () => {
await assertContractVariable(
ProxyAdmin,
'addressManager',
AddressManager.address
)
assert(
(await ProxyAdmin.implementationName(
getDeploymentAddress(hre, 'Proxy__OVM_L1CrossDomainMessenger')
)) === 'OVM_L1CrossDomainMessenger'
)
assert(
(await ProxyAdmin.proxyType(
getDeploymentAddress(hre, 'Proxy__OVM_L1CrossDomainMessenger')
)) === 2
)
assert(
(await ProxyAdmin.proxyType(
getDeploymentAddress(hre, 'Proxy__OVM_L1StandardBridge')
)) === 1
)
},
2: async () => {
await assertContractVariable(L1CrossDomainMessenger, 'paused', true)
const deads = [
'Proxy__OVM_L1CrossDomainMessenger',
'Proxy__OVM_L1StandardBridge',
'OVM_CanonicalTransactionChain',
'OVM_L2CrossDomainMessenger',
'OVM_DecompressionPrecompileAddress',
'OVM_Sequencer',
'OVM_Proposer',
'OVM_ChainStorageContainer-CTC-batches',
'OVM_ChainStorageContainer-CTC-queue',
'OVM_CanonicalTransactionChain',
'OVM_StateCommitmentChain',
'OVM_BondManager',
'OVM_ExecutionManager',
'OVM_FraudVerifier',
'OVM_StateManagerFactory',
'OVM_StateTransitionerFactory',
'OVM_SafetyChecker',
'OVM_L1MultiMessageRelayer',
]
for (const dead of deads) {
assert(
(await AddressManager.getAddress(dead)) ===
ethers.constants.AddressZero
)
}
},
3: async () => {
await assertContractVariable(AddressManager, 'owner', ProxyAdmin.address)
assert(
(await L1StandardBridgeProxy.callStatic.getOwner({
from: ethers.constants.AddressZero,
})) === ProxyAdmin.address
)
},
4: async () => {
// Check L2OutputOracle was initialized properly.
await assertContractVariable(
L2OutputOracle,
'latestBlockNumber',
hre.deployConfig.l2OutputOracleStartingBlockNumber
)
await assertContractVariable(
L2OutputOracle,
'proposer',
hre.deployConfig.l2OutputOracleProposer
)
await assertContractVariable(
L2OutputOracle,
'owner',
hre.deployConfig.l2OutputOracleOwner
)
if (
hre.deployConfig.l2OutputOracleGenesisL2Output !==
ethers.constants.HashZero
) {
const genesisOutput = await L2OutputOracle.getL2Output(
hre.deployConfig.l2OutputOracleStartingBlockNumber
)
assert(
genesisOutput.outputRoot ===
hre.deployConfig.l2OutputOracleGenesisL2Output,
`L2OutputOracle was not initialized with the correct genesis output root`
)
}
// Check OptimismPortal was initialized properly.
await assertContractVariable(
OptimismPortal,
'l2Sender',
'0x000000000000000000000000000000000000dEaD'
)
const resourceParams = await OptimismPortal.params()
assert(
resourceParams.prevBaseFee.eq(await OptimismPortal.INITIAL_BASE_FEE()),
`OptimismPortal was not initialized with the correct initial base fee`
)
assert(
resourceParams.prevBoughtGas.eq(0),
`OptimismPortal was not initialized with the correct initial bought gas`
)
assert(
!resourceParams.prevBlockNum.eq(0),
`OptimismPortal was not initialized with the correct initial block number`
)
assert(
(await hre.ethers.provider.getBalance(OptimismPortal.address)).gt(0)
)
// Check L1CrossDomainMessenger was initialized properly.
try {
await L1CrossDomainMessenger.xDomainMessageSender()
assert(false, `L1CrossDomainMessenger was not initialized properly`)
} catch (err) {
assert(
err.message.includes('xDomainMessageSender is not set'),
`L1CrossDomainMessenger was not initialized properly`
)
}
await assertContractVariable(
L1CrossDomainMessenger,
'owner',
MigrationSystemDictator.address
)
// Check L1StandardBridge was initialized properly.
await assertContractVariable(
L1StandardBridge,
'messenger',
L1CrossDomainMessenger.address
)
assert(
(await hre.ethers.provider.getBalance(L1StandardBridge.address)).eq(0)
)
// Check OptimismMintableERC20Factory was initialized properly.
await assertContractVariable(
OptimismMintableERC20Factory,
'bridge',
L1StandardBridge.address
)
// Check L1ERC721Bridge was initialized properly.
await assertContractVariable(
L1ERC721Bridge,
'messenger',
L1CrossDomainMessenger.address
)
},
5: async () => {
await assertContractVariable(L1CrossDomainMessenger, 'paused', false)
},
6: async () => {
await assertContractVariable(
L1CrossDomainMessenger,
'owner',
hre.deployConfig.finalSystemOwner
)
await assertContractVariable(
ProxyAdmin,
'owner',
hre.deployConfig.finalSystemOwner
)
},
}
for (let i = 1; i <= 6; i++) {
if (isLiveDeployer) {
console.log(`Executing step ${i}...`)
await MigrationSystemDictator[`step${i}`]()
if ((await MigrationSystemDictator.currentStep()) === i) {
if (isLiveDeployer) {
console.log(`Executing step ${i}...`)
await MigrationSystemDictator[`step${i}`]()
} else {
console.log(`Please execute step ${i}...`)
}
await awaitCondition(async () => {
const step = await MigrationSystemDictator.currentStep()
return step === i + 1
})
// Run post step checks
await checks[i]()
} else {
console.log(`Please execute step ${i}...`)
console.log(`Step ${i} executed`)
}
await awaitCondition(async () => {
const step = await MigrationSystemDictator.currentStep()
return Number(step) === i + 1
})
}
}
......
......@@ -299,6 +299,21 @@ export const getContractFromArtifact = async (
})
}
export const getContractsFromArtifacts = async (
hre: any,
configs: Array<{
name: string
iface?: string
signerOrProvider?: Signer | Provider | string
}>
): Promise<ethers.Contract[]> => {
const contracts = []
for (const config of configs) {
contracts.push(await getContractFromArtifact(hre, config.name, config))
}
return contracts
}
export const isHardhatNode = async (hre) => {
return (await getChainId(hre.ethers.provider)) === 31337
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment