Commit 1362c808 authored by Kelvin Fichter's avatar Kelvin Fichter

feat(ctb): unify fresh and migration deployments

Removes the concept of a "Fresh" deployment and deploys some legacy
contracts where necessary so that all new deployments will mirror the
mainnet system. Although this enshrines some legacy code, it means that
we won't have multiple conflicting deployments in the future.
parent b63f5760
...@@ -61,7 +61,7 @@ def main(): ...@@ -61,7 +61,7 @@ def main():
addresses = read_json(addresses_json_path) addresses = read_json(addresses_json_path)
else: else:
log.info('Deploying contracts.') log.info('Deploying contracts.')
run_command(['yarn', 'hardhat', '--network', 'devnetL1', 'deploy', '--tags', 'fresh'], env={ run_command(['yarn', 'hardhat', '--network', 'devnetL1', 'deploy'], env={
'CHAIN_ID': '900', 'CHAIN_ID': '900',
'L1_RPC': 'http://localhost:8545', 'L1_RPC': 'http://localhost:8545',
'PRIVATE_KEY_DEPLOYER': 'ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' 'PRIVATE_KEY_DEPLOYER': 'ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { L2OutputOracle } from "../L1/L2OutputOracle.sol";
import { OptimismPortal } from "../L1/OptimismPortal.sol";
import { SystemConfig } from "../L1/SystemConfig.sol";
import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol";
import { BaseSystemDictator } from "./BaseSystemDictator.sol";
/**
* @title FreshSystemDictator
* @notice The FreshSystemDictator is responsible for coordinating initialization of a fresh
* deployment of the Optimism system. We expect that all proxies and implementations
* already be deployed before this contract is used.
*/
contract FreshSystemDictator is BaseSystemDictator {
/**
* @param _config System configuration.
*/
constructor(DeployConfig memory _config) BaseSystemDictator(_config) {}
/**
* @notice Upgrades and initializes proxy contracts.
*/
function step1() external onlyOwner step(1) {
// Upgrade and initialize the L2OutputOracle.
config.globalConfig.proxyAdmin.upgradeAndCall(
payable(config.proxyAddressConfig.l2OutputOracleProxy),
address(config.implementationAddressConfig.l2OutputOracleImpl),
abi.encodeCall(
L2OutputOracle.initialize,
(
config.l2OutputOracleConfig.l2OutputOracleGenesisL2Output,
config.l2OutputOracleConfig.l2OutputOracleProposer,
config.l2OutputOracleConfig.l2OutputOracleOwner
)
)
);
// Upgrade and initialize the OptimismPortal.
config.globalConfig.proxyAdmin.upgradeAndCall(
payable(config.proxyAddressConfig.optimismPortalProxy),
address(config.implementationAddressConfig.optimismPortalImpl),
abi.encodeCall(OptimismPortal.initialize, ())
);
// Upgrade and initialize the L1CrossDomainMessenger.
config.globalConfig.proxyAdmin.upgradeAndCall(
payable(config.proxyAddressConfig.l1CrossDomainMessengerProxy),
address(config.implementationAddressConfig.l1CrossDomainMessengerImpl),
abi.encodeCall(L1CrossDomainMessenger.initialize, (config.globalConfig.finalOwner))
);
// Upgrade the L1StandardBridge (no initializer).
config.globalConfig.proxyAdmin.upgrade(
payable(config.proxyAddressConfig.l1StandardBridgeProxy),
address(config.implementationAddressConfig.l1StandardBridgeImpl)
);
// Upgrade the OptimismMintableERC20Factory (no initializer).
config.globalConfig.proxyAdmin.upgrade(
payable(config.proxyAddressConfig.optimismMintableERC20FactoryProxy),
address(config.implementationAddressConfig.optimismMintableERC20FactoryImpl)
);
// Upgrade the L1ERC721Bridge (no initializer).
config.globalConfig.proxyAdmin.upgrade(
payable(config.proxyAddressConfig.l1ERC721BridgeProxy),
address(config.implementationAddressConfig.l1ERC721BridgeImpl)
);
// Upgrade and initialize the SystemConfig.
config.globalConfig.proxyAdmin.upgradeAndCall(
payable(config.proxyAddressConfig.systemConfigProxy),
address(config.implementationAddressConfig.systemConfigImpl),
abi.encodeCall(
SystemConfig.initialize,
(
config.systemConfigConfig.owner,
config.systemConfigConfig.overhead,
config.systemConfigConfig.scalar,
config.systemConfigConfig.batcherHash,
config.systemConfigConfig.gasLimit
)
)
);
}
/**
* @notice Transfers ownership to final owner.
*/
function step2() external onlyOwner step(2) {
// Transfer ownership of the ProxyAdmin to the final owner.
config.globalConfig.proxyAdmin.transferOwnership(config.globalConfig.finalOwner);
}
}
...@@ -143,10 +143,6 @@ contract MigrationSystemDictator is BaseSystemDictator { ...@@ -143,10 +143,6 @@ contract MigrationSystemDictator is BaseSystemDictator {
* @notice Upgrades and initializes proxy contracts. * @notice Upgrades and initializes proxy contracts.
*/ */
function step5() external onlyOwner step(5) { function step5() external onlyOwner step(5) {
// Pause the L1CrossDomainMessenger. Now we use the real pause() function because by the
// time we're done here we'll have access to the unpause() function.
L1CrossDomainMessenger(config.proxyAddressConfig.l1CrossDomainMessengerProxy).pause();
// Upgrade and initialize the L2OutputOracle. // Upgrade and initialize the L2OutputOracle.
config.globalConfig.proxyAdmin.upgradeAndCall( config.globalConfig.proxyAdmin.upgradeAndCall(
payable(config.proxyAddressConfig.l2OutputOracleProxy), payable(config.proxyAddressConfig.l2OutputOracleProxy),
...@@ -168,13 +164,34 @@ contract MigrationSystemDictator is BaseSystemDictator { ...@@ -168,13 +164,34 @@ contract MigrationSystemDictator is BaseSystemDictator {
abi.encodeCall(OptimismPortal.initialize, ()) abi.encodeCall(OptimismPortal.initialize, ())
); );
// Upgrade the L1CrossDomainMessenger. No initializer because this is // Upgrade the L1CrossDomainMessenger.
// already initialized.
config.globalConfig.proxyAdmin.upgrade( config.globalConfig.proxyAdmin.upgrade(
payable(config.proxyAddressConfig.l1CrossDomainMessengerProxy), payable(config.proxyAddressConfig.l1CrossDomainMessengerProxy),
address(config.implementationAddressConfig.l1CrossDomainMessengerImpl) address(config.implementationAddressConfig.l1CrossDomainMessengerImpl)
); );
// Try to initialize the L1CrossDomainMessenger, only fail if it's already been initialized.
try
L1CrossDomainMessenger(config.proxyAddressConfig.l1CrossDomainMessengerProxy)
.initialize(address(this))
{
// L1CrossDomainMessenger is the one annoying edge case difference between existing
// networks and fresh networks because in existing networks it'll already be
// initialized but in fresh networks it won't be. Try/catch is the easiest and most
// consistent way to handle this because initialized() is not exposed publicly.
} catch Error(string memory reason) {
require(
keccak256(abi.encodePacked(reason)) ==
keccak256("Initializable: contract is already initialized"),
string.concat(
"MigrationSystemDictator: unexpected error initializing L1XDM: ",
reason
)
);
} catch {
revert("MigrationSystemDictator: unexpected error initializing L1XDM (no reason)");
}
// Transfer ETH from the L1StandardBridge to the OptimismPortal. // Transfer ETH from the L1StandardBridge to the OptimismPortal.
config.globalConfig.proxyAdmin.upgradeAndCall( config.globalConfig.proxyAdmin.upgradeAndCall(
payable(config.proxyAddressConfig.l1StandardBridgeProxy), payable(config.proxyAddressConfig.l1StandardBridgeProxy),
...@@ -215,6 +232,9 @@ contract MigrationSystemDictator is BaseSystemDictator { ...@@ -215,6 +232,9 @@ contract MigrationSystemDictator is BaseSystemDictator {
) )
) )
); );
// Pause the L1CrossDomainMessenger, chance to check that everything is OK.
L1CrossDomainMessenger(config.proxyAddressConfig.l1CrossDomainMessengerProxy).pause();
} }
/** /**
......
...@@ -19,6 +19,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -19,6 +19,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['ProxyAdmin', 'fresh', 'migration'] deployFn.tags = ['ProxyAdmin']
export default deployFn export default deployFn
...@@ -3,22 +3,22 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' ...@@ -3,22 +3,22 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
import { import {
assertContractVariable, assertContractVariable,
deployAndVerifyAndThen, deployAndVerifyAndThen,
getDeploymentAddress,
} from '../src/deploy-utils' } from '../src/deploy-utils'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const proxyAdmin = await getDeploymentAddress(hre, 'ProxyAdmin') const { deployer } = await hre.getNamedAccounts()
await deployAndVerifyAndThen({ await deployAndVerifyAndThen({
hre, hre,
name: 'L1StandardBridgeProxy', name: 'Lib_AddressManager',
contract: 'Proxy', contract: 'AddressManager',
args: [proxyAdmin], args: [],
postDeployAction: async (contract) => { postDeployAction: async (contract) => {
await assertContractVariable(contract, 'admin', proxyAdmin) // Owner is temporarily set to the deployer.
await assertContractVariable(contract, 'owner', deployer)
}, },
}) })
} }
deployFn.tags = ['L1StandardBridgeProxy', 'fresh'] deployFn.tags = ['AddressManager']
export default deployFn export default deployFn
import { DeployFunction } from 'hardhat-deploy/dist/types'
import {
assertContractVariable,
deployAndVerifyAndThen,
} from '../src/deploy-utils'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
await deployAndVerifyAndThen({
hre,
name: 'Proxy__OVM_L1StandardBridge',
contract: 'L1ChugSplashProxy',
args: [deployer],
postDeployAction: async (contract) => {
await assertContractVariable(contract, 'getOwner', deployer)
},
})
}
deployFn.tags = ['L1StandardBridgeProxy']
export default deployFn
import { DeployFunction } from 'hardhat-deploy/dist/types'
import {
assertContractVariable,
deployAndVerifyAndThen,
getDeploymentAddress,
} from '../src/deploy-utils'
const deployFn: DeployFunction = async (hre) => {
const proxyAdmin = await getDeploymentAddress(hre, 'ProxyAdmin')
await deployAndVerifyAndThen({
hre,
name: 'L1CrossDomainMessengerProxy',
contract: 'Proxy',
args: [proxyAdmin],
postDeployAction: async (contract) => {
await assertContractVariable(contract, 'admin', proxyAdmin)
},
})
}
deployFn.tags = ['L1CrossDomainMessengerProxy', 'fresh']
export default deployFn
...@@ -19,6 +19,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -19,6 +19,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['L2OutputOracleProxy', 'fresh', 'migration'] deployFn.tags = ['L2OutputOracleProxy']
export default deployFn export default deployFn
import { DeployFunction } from 'hardhat-deploy/dist/types'
import {
deployAndVerifyAndThen,
getDeploymentAddress,
} from '../src/deploy-utils'
const deployFn: DeployFunction = async (hre) => {
const addressManager = await getDeploymentAddress(hre, 'Lib_AddressManager')
await deployAndVerifyAndThen({
hre,
name: 'Proxy__OVM_L1CrossDomainMessenger',
contract: 'ResolvedDelegateProxy',
args: [addressManager, 'OVM_L1CrossDomainMessenger'],
})
}
deployFn.tags = ['L1CrossDomainMessengerProxy']
export default deployFn
...@@ -19,6 +19,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -19,6 +19,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['OptimismPortalProxy', 'fresh', 'migration'] deployFn.tags = ['OptimismPortalProxy']
export default deployFn export default deployFn
...@@ -19,6 +19,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -19,6 +19,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['OptimismMintableERC20FactoryProxy', 'fresh', 'migration'] deployFn.tags = ['OptimismMintableERC20FactoryProxy']
export default deployFn export default deployFn
...@@ -19,6 +19,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -19,6 +19,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['L1ERC721BridgeProxy', 'fresh', 'migration'] deployFn.tags = ['L1ERC721BridgeProxy']
export default deployFn export default deployFn
...@@ -19,6 +19,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -19,6 +19,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['SystemConfigProxy', 'fresh', 'migration'] deployFn.tags = ['SystemConfigProxy']
export default deployFn export default deployFn
...@@ -12,6 +12,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -12,6 +12,7 @@ const deployFn: DeployFunction = async (hre) => {
hre, hre,
'OptimismPortalProxy' 'OptimismPortalProxy'
) )
await deployAndVerifyAndThen({ await deployAndVerifyAndThen({
hre, hre,
name: 'L1CrossDomainMessenger', name: 'L1CrossDomainMessenger',
...@@ -31,6 +32,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -31,6 +32,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['L1CrossDomainMessengerImpl', 'fresh', 'migration'] deployFn.tags = ['L1CrossDomainMessengerImpl']
export default deployFn export default deployFn
import { ethers } from 'ethers'
import { DeployFunction } from 'hardhat-deploy/dist/types' import { DeployFunction } from 'hardhat-deploy/dist/types'
import { predeploys } from '../src' import { predeploys } from '../src'
...@@ -9,18 +8,10 @@ import { ...@@ -9,18 +8,10 @@ import {
} from '../src/deploy-utils' } from '../src/deploy-utils'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
let L1CrossDomainMessengerProxy: ethers.Contract const L1CrossDomainMessengerProxy = await getContractFromArtifact(
try { hre,
L1CrossDomainMessengerProxy = await getContractFromArtifact( 'Proxy__OVM_L1CrossDomainMessenger'
hre, )
'Proxy__OVM_L1CrossDomainMessenger'
)
} catch {
L1CrossDomainMessengerProxy = await getContractFromArtifact(
hre,
'L1CrossDomainMessengerProxy'
)
}
await deployAndVerifyAndThen({ await deployAndVerifyAndThen({
hre, hre,
...@@ -41,6 +32,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -41,6 +32,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['L1StandardBridgeImpl', 'fresh', 'migration'] deployFn.tags = ['L1StandardBridgeImpl']
export default deployFn export default deployFn
...@@ -91,6 +91,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -91,6 +91,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['L2OutputOracleImpl', 'fresh', 'migration'] deployFn.tags = ['L2OutputOracleImpl']
export default deployFn export default deployFn
...@@ -12,6 +12,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -12,6 +12,7 @@ const deployFn: DeployFunction = async (hre) => {
hre, hre,
'L2OutputOracleProxy' 'L2OutputOracleProxy'
) )
await deployAndVerifyAndThen({ await deployAndVerifyAndThen({
hre, hre,
name: 'OptimismPortal', name: 'OptimismPortal',
...@@ -34,6 +35,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -34,6 +35,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['OptimismPortalImpl', 'fresh', 'migration'] deployFn.tags = ['OptimismPortalImpl']
export default deployFn export default deployFn
import { ethers } from 'ethers'
import { DeployFunction } from 'hardhat-deploy/dist/types' import { DeployFunction } from 'hardhat-deploy/dist/types'
import { import {
...@@ -8,18 +7,10 @@ import { ...@@ -8,18 +7,10 @@ import {
} from '../src/deploy-utils' } from '../src/deploy-utils'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
let L1StandardBridgeProxy: ethers.Contract const L1StandardBridgeProxy = await getContractFromArtifact(
try { hre,
L1StandardBridgeProxy = await getContractFromArtifact( 'Proxy__OVM_L1StandardBridge'
hre, )
'Proxy__OVM_L1StandardBridge'
)
} catch (e) {
L1StandardBridgeProxy = await getContractFromArtifact(
hre,
'L1StandardBridgeProxy'
)
}
await deployAndVerifyAndThen({ await deployAndVerifyAndThen({
hre, hre,
...@@ -35,6 +26,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -35,6 +26,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['OptimismMintableERC20FactoryImpl', 'fresh', 'migration'] deployFn.tags = ['OptimismMintableERC20FactoryImpl']
export default deployFn export default deployFn
import { ethers } from 'ethers'
import { DeployFunction } from 'hardhat-deploy/dist/types' import { DeployFunction } from 'hardhat-deploy/dist/types'
import { predeploys } from '../src' import { predeploys } from '../src'
...@@ -9,18 +8,10 @@ import { ...@@ -9,18 +8,10 @@ import {
} from '../src/deploy-utils' } from '../src/deploy-utils'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
let L1CrossDomainMessengerProxy: ethers.Contract const L1CrossDomainMessengerProxy = await getContractFromArtifact(
try { hre,
L1CrossDomainMessengerProxy = await getContractFromArtifact( 'Proxy__OVM_L1CrossDomainMessenger'
hre, )
'Proxy__OVM_L1CrossDomainMessenger'
)
} catch {
L1CrossDomainMessengerProxy = await getContractFromArtifact(
hre,
'L1CrossDomainMessengerProxy'
)
}
await deployAndVerifyAndThen({ await deployAndVerifyAndThen({
hre, hre,
...@@ -36,6 +27,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -36,6 +27,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['L1ERC721BridgeImpl', 'fresh', 'migration'] deployFn.tags = ['L1ERC721BridgeImpl']
export default deployFn export default deployFn
...@@ -11,6 +11,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -11,6 +11,7 @@ const deployFn: DeployFunction = async (hre) => {
hre, hre,
'OptimismPortalProxy' 'OptimismPortalProxy'
) )
await deployAndVerifyAndThen({ await deployAndVerifyAndThen({
hre, hre,
name: 'PortalSender', name: 'PortalSender',
...@@ -25,6 +26,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -25,6 +26,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['PortalSenderImpl', 'fresh', 'migration'] deployFn.tags = ['PortalSenderImpl']
export default deployFn export default deployFn
import { DeployFunction } from 'hardhat-deploy/dist/types'
import '@eth-optimism/hardhat-deploy-config'
import 'hardhat-deploy'
import {
deployAndVerifyAndThen,
assertDictatorConfig,
makeDictatorConfig,
} from '../src/deploy-utils'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const config = await makeDictatorConfig(
hre,
deployer,
hre.deployConfig.finalSystemOwner,
true
)
await deployAndVerifyAndThen({
hre,
name: 'FreshSystemDictator',
args: [config],
postDeployAction: async (contract) => {
await assertDictatorConfig(contract, config)
},
})
}
deployFn.tags = ['FreshSystemDictator', 'fresh']
export default deployFn
...@@ -11,6 +11,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -11,6 +11,7 @@ const deployFn: DeployFunction = async (hre) => {
hre.deployConfig.batchSenderAddress, hre.deployConfig.batchSenderAddress,
32 32
) )
await deployAndVerifyAndThen({ await deployAndVerifyAndThen({
hre, hre,
name: 'SystemConfig', name: 'SystemConfig',
...@@ -46,6 +47,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -46,6 +47,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['SystemConfigImpl', 'fresh', 'migration'] deployFn.tags = ['SystemConfigImpl']
export default deployFn export default deployFn
import assert from 'assert'
import { ethers } from 'ethers'
import { DeployFunction } from 'hardhat-deploy/dist/types'
import '@eth-optimism/hardhat-deploy-config'
import 'hardhat-deploy'
import {
assertContractVariable,
getContractFromArtifact,
} from '../src/deploy-utils'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const ProxyAdmin = await getContractFromArtifact(hre, 'ProxyAdmin', {
signerOrProvider: deployer,
})
const FreshSystemDictator = await getContractFromArtifact(
hre,
'FreshSystemDictator',
{
signerOrProvider: deployer,
}
)
if ((await ProxyAdmin.owner()) !== FreshSystemDictator.address) {
console.log(`Transferring proxy admin ownership to the FreshSystemDictator`)
await ProxyAdmin.transferOwnership(FreshSystemDictator.address)
} else {
console.log(`Proxy admin already owned by the FreshSystemDictator`)
}
if ((await FreshSystemDictator.currentStep()) === 1) {
console.log(`Executing step 1`)
await FreshSystemDictator.step1()
// Check L2OutputOracle was initialized properly.
const L2OutputOracle = await getContractFromArtifact(
hre,
'L2OutputOracleProxy',
{
iface: 'L2OutputOracle',
}
)
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.
const OptimismPortal = await getContractFromArtifact(
hre,
'OptimismPortalProxy',
{
iface: 'OptimismPortal',
}
)
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`
)
// Check L1CrossDomainMessenger was initialized properly.
const L1CrossDomainMessenger = await getContractFromArtifact(
hre,
'L1CrossDomainMessengerProxy',
{
iface: 'L1CrossDomainMessenger',
}
)
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',
hre.deployConfig.finalSystemOwner
)
// Check L1StandardBridge was initialized properly.
const L1StandardBridge = await getContractFromArtifact(
hre,
'L1StandardBridgeProxy',
{
iface: 'L1StandardBridge',
}
)
await assertContractVariable(
L1StandardBridge,
'messenger',
L1CrossDomainMessenger.address
)
// Check OptimismMintableERC20Factory was initialized properly.
const OptimismMintableERC20Factory = await getContractFromArtifact(
hre,
'OptimismMintableERC20FactoryProxy',
{
iface: 'OptimismMintableERC20Factory',
}
)
await assertContractVariable(
OptimismMintableERC20Factory,
'bridge',
L1StandardBridge.address
)
// Check L1ERC721Bridge was initialized properly.
const L1ERC721Bridge = await getContractFromArtifact(
hre,
'L1ERC721BridgeProxy',
{
iface: 'L1ERC721Bridge',
}
)
await assertContractVariable(
L1ERC721Bridge,
'messenger',
L1CrossDomainMessenger.address
)
} else {
console.log(`Step 1 executed`)
}
if ((await FreshSystemDictator.currentStep()) === 2) {
console.log(`Executing step 2`)
await FreshSystemDictator.step2()
// Check the ProxyAdmin owner was changed properly.
await assertContractVariable(
ProxyAdmin,
'owner',
hre.deployConfig.finalSystemOwner
)
} else {
console.log(`Step 2 executed`)
}
}
deployFn.tags = ['FreshSystemDictatorSteps', 'fresh']
export default deployFn
...@@ -73,6 +73,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -73,6 +73,6 @@ const deployFn: DeployFunction = async (hre) => {
}) })
} }
deployFn.tags = ['MigrationSystemDictator', 'migration'] deployFn.tags = ['MigrationSystemDictator']
export default deployFn export default deployFn
...@@ -17,9 +17,24 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -17,9 +17,24 @@ const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts() const { deployer } = await hre.getNamedAccounts()
let isLiveDeployer = false let isLiveDeployer = false
if (hre.deployConfig.controller === deployer) { let controller = hre.deployConfig.controller
console.log('using a live deployer') if (controller === ethers.constants.AddressZero) {
isLiveDeployer = true 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.`
)
console.log('using a live deployer')
isLiveDeployer = true
controller = deployer
} else {
throw new Error(
`controller address MUST NOT be the deployer on live networks`
)
}
} }
// Set up required contract references. // Set up required contract references.
...@@ -116,6 +131,8 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -116,6 +131,8 @@ const deployFn: DeployFunction = async (hre) => {
// Transfer ownership of the L1CrossDomainMessenger to MigrationSystemDictator. // Transfer ownership of the L1CrossDomainMessenger to MigrationSystemDictator.
if ( if (
(await AddressManager.getAddress('OVM_L1CrossDomainMessenger')) !==
ethers.constants.AddressZero &&
(await L1CrossDomainMessenger.owner()) !== MigrationSystemDictator.address (await L1CrossDomainMessenger.owner()) !== MigrationSystemDictator.address
) { ) {
if (isLiveDeployer) { if (isLiveDeployer) {
...@@ -279,7 +296,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -279,7 +296,7 @@ const deployFn: DeployFunction = async (hre) => {
`OptimismPortal was not initialized with the correct initial block number` `OptimismPortal was not initialized with the correct initial block number`
) )
assert( assert(
(await hre.ethers.provider.getBalance(OptimismPortal.address)).gt(0) (await hre.ethers.provider.getBalance(L1StandardBridge.address)).eq(0)
) )
// Check L1CrossDomainMessenger was initialized properly. // Check L1CrossDomainMessenger was initialized properly.
...@@ -375,6 +392,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -375,6 +392,6 @@ const deployFn: DeployFunction = async (hre) => {
} }
} }
deployFn.tags = ['MigrationSystemDictatorSteps', 'migration'] deployFn.tags = ['MigrationSystemDictatorSteps']
export default deployFn export default deployFn
...@@ -12,6 +12,9 @@ import './tasks' ...@@ -12,6 +12,9 @@ import './tasks'
const config: HardhatUserConfig = { const config: HardhatUserConfig = {
networks: { networks: {
hardhat: {
live: false,
},
devnetL1: { devnetL1: {
live: false, live: false,
url: 'http://localhost:8545', url: 'http://localhost:8545',
...@@ -341,8 +344,14 @@ const config: HardhatUserConfig = { ...@@ -341,8 +344,14 @@ const config: HardhatUserConfig = {
], ],
deployments: { deployments: {
goerli: ['../contracts/deployments/goerli'], goerli: ['../contracts/deployments/goerli'],
mainnet: ['../contracts/deployments/mainnet'], mainnet: [
'mainnet-forked': ['../contracts/deployments/mainnet'], '../contracts/deployments/mainnet',
'../contracts-periphery/deployments/mainnet',
],
'mainnet-forked': [
'../contracts/deployments/mainnet',
'../contracts-periphery/deployments/mainnet',
],
}, },
}, },
solidity: { solidity: {
......
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