Commit b94e9cb5 authored by Matthew Slipper's avatar Matthew Slipper

ctb: Add system config deployment

parent 8ed14a8f
...@@ -8,3 +8,5 @@ broadcast ...@@ -8,3 +8,5 @@ broadcast
genesis.json genesis.json
src/contract-artifacts.ts src/contract-artifacts.ts
tmp-artifacts tmp-artifacts
deployments/mainnet-forked
deploy-config/mainnet-forked.json
...@@ -7,6 +7,7 @@ import { OptimismPortal } from "../L1/OptimismPortal.sol"; ...@@ -7,6 +7,7 @@ import { OptimismPortal } from "../L1/OptimismPortal.sol";
import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol"; import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol";
import { L1StandardBridge } from "../L1/L1StandardBridge.sol"; import { L1StandardBridge } from "../L1/L1StandardBridge.sol";
import { L1ERC721Bridge } from "../L1/L1ERC721Bridge.sol"; import { L1ERC721Bridge } from "../L1/L1ERC721Bridge.sol";
import { SystemConfig } from "../L1/SystemConfig.sol";
import { OptimismMintableERC20Factory } from "../universal/OptimismMintableERC20Factory.sol"; import { OptimismMintableERC20Factory } from "../universal/OptimismMintableERC20Factory.sol";
import { AddressManager } from "../legacy/AddressManager.sol"; import { AddressManager } from "../legacy/AddressManager.sol";
import { PortalSender } from "./PortalSender.sol"; import { PortalSender } from "./PortalSender.sol";
...@@ -37,6 +38,7 @@ contract BaseSystemDictator is Ownable { ...@@ -37,6 +38,7 @@ contract BaseSystemDictator is Ownable {
address l1StandardBridgeProxy; address l1StandardBridgeProxy;
address optimismMintableERC20FactoryProxy; address optimismMintableERC20FactoryProxy;
address l1ERC721BridgeProxy; address l1ERC721BridgeProxy;
address systemConfigProxy;
} }
/** /**
...@@ -50,6 +52,7 @@ contract BaseSystemDictator is Ownable { ...@@ -50,6 +52,7 @@ contract BaseSystemDictator is Ownable {
OptimismMintableERC20Factory optimismMintableERC20FactoryImpl; OptimismMintableERC20Factory optimismMintableERC20FactoryImpl;
L1ERC721Bridge l1ERC721BridgeImpl; L1ERC721Bridge l1ERC721BridgeImpl;
PortalSender portalSenderImpl; PortalSender portalSenderImpl;
SystemConfig systemConfigImpl;
} }
/** /**
...@@ -61,20 +64,32 @@ contract BaseSystemDictator is Ownable { ...@@ -61,20 +64,32 @@ contract BaseSystemDictator is Ownable {
address l2OutputOracleOwner; address l2OutputOracleOwner;
} }
/**
* @notice Values for the system config contract.
*/
struct SystemConfigConfig {
address owner;
uint256 overhead;
uint256 scalar;
bytes32 batcherHash;
uint64 gasLimit;
}
/** /**
* @notice Combined system configuration. * @notice Combined system configuration.
*/ */
struct SystemConfig { struct DeployConfig {
GlobalConfig globalConfig; GlobalConfig globalConfig;
ProxyAddressConfig proxyAddressConfig; ProxyAddressConfig proxyAddressConfig;
ImplementationAddressConfig implementationAddressConfig; ImplementationAddressConfig implementationAddressConfig;
L2OutputOracleConfig l2OutputOracleConfig; L2OutputOracleConfig l2OutputOracleConfig;
SystemConfigConfig systemConfigConfig;
} }
/** /**
* @notice System configuration. * @notice System configuration.
*/ */
SystemConfig public config; DeployConfig public config;
/** /**
* @notice Current step; * @notice Current step;
...@@ -95,7 +110,7 @@ contract BaseSystemDictator is Ownable { ...@@ -95,7 +110,7 @@ contract BaseSystemDictator is Ownable {
/** /**
* @param _config System configuration. * @param _config System configuration.
*/ */
constructor(SystemConfig memory _config) Ownable() { constructor(DeployConfig memory _config) Ownable() {
config = _config; config = _config;
_transferOwnership(config.globalConfig.controller); _transferOwnership(config.globalConfig.controller);
} }
......
...@@ -3,6 +3,7 @@ pragma solidity 0.8.15; ...@@ -3,6 +3,7 @@ pragma solidity 0.8.15;
import { L2OutputOracle } from "../L1/L2OutputOracle.sol"; import { L2OutputOracle } from "../L1/L2OutputOracle.sol";
import { OptimismPortal } from "../L1/OptimismPortal.sol"; import { OptimismPortal } from "../L1/OptimismPortal.sol";
import { SystemConfig } from "../L1/SystemConfig.sol";
import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol"; import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol";
import { BaseSystemDictator } from "./BaseSystemDictator.sol"; import { BaseSystemDictator } from "./BaseSystemDictator.sol";
...@@ -16,7 +17,7 @@ contract FreshSystemDictator is BaseSystemDictator { ...@@ -16,7 +17,7 @@ contract FreshSystemDictator is BaseSystemDictator {
/** /**
* @param _config System configuration. * @param _config System configuration.
*/ */
constructor(SystemConfig memory _config) BaseSystemDictator(_config) {} constructor(DeployConfig memory _config) BaseSystemDictator(_config) {}
/** /**
* @notice Upgrades and initializes proxy contracts. * @notice Upgrades and initializes proxy contracts.
...@@ -67,6 +68,22 @@ contract FreshSystemDictator is BaseSystemDictator { ...@@ -67,6 +68,22 @@ contract FreshSystemDictator is BaseSystemDictator {
payable(config.proxyAddressConfig.l1ERC721BridgeProxy), payable(config.proxyAddressConfig.l1ERC721BridgeProxy),
address(config.implementationAddressConfig.l1ERC721BridgeImpl) 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
)
)
);
} }
/** /**
......
...@@ -7,6 +7,7 @@ import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol"; ...@@ -7,6 +7,7 @@ import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol";
import { L1ChugSplashProxy } from "../legacy/L1ChugSplashProxy.sol"; import { L1ChugSplashProxy } from "../legacy/L1ChugSplashProxy.sol";
import { ProxyAdmin } from "../universal/ProxyAdmin.sol"; import { ProxyAdmin } from "../universal/ProxyAdmin.sol";
import { PortalSender } from "./PortalSender.sol"; import { PortalSender } from "./PortalSender.sol";
import { SystemConfig } from "../L1/SystemConfig.sol";
import { BaseSystemDictator } from "./BaseSystemDictator.sol"; import { BaseSystemDictator } from "./BaseSystemDictator.sol";
/** /**
...@@ -19,7 +20,7 @@ contract MigrationSystemDictator is BaseSystemDictator { ...@@ -19,7 +20,7 @@ contract MigrationSystemDictator is BaseSystemDictator {
/** /**
* @param _config System configuration. * @param _config System configuration.
*/ */
constructor(SystemConfig memory _config) BaseSystemDictator(_config) {} constructor(DeployConfig memory _config) BaseSystemDictator(_config) {}
/** /**
* @notice Configures the ProxyAdmin contract. * @notice Configures the ProxyAdmin contract.
...@@ -153,6 +154,22 @@ contract MigrationSystemDictator is BaseSystemDictator { ...@@ -153,6 +154,22 @@ contract MigrationSystemDictator is BaseSystemDictator {
payable(config.proxyAddressConfig.l1ERC721BridgeProxy), payable(config.proxyAddressConfig.l1ERC721BridgeProxy),
address(config.implementationAddressConfig.l1ERC721BridgeImpl) 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
)
)
);
} }
/** /**
......
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: 'SystemConfigProxy',
contract: 'Proxy',
args: [proxyAdmin],
postDeployAction: async (contract) => {
await assertContractVariable(contract, 'admin', proxyAdmin)
},
})
}
deployFn.tags = ['SystemConfigProxy', 'fresh', 'migration']
export default deployFn
import { DeployFunction } from 'hardhat-deploy/dist/types'
import '@eth-optimism/hardhat-deploy-config'
import {
assertContractVariable,
deployAndVerifyAndThen,
} from '../src/deploy-utils'
const deployFn: DeployFunction = async (hre) => {
const batcherHash = hre.ethers.utils.hexZeroPad(
hre.deployConfig.batchSenderAddress,
32
)
await deployAndVerifyAndThen({
hre,
name: 'SystemConfig',
args: [
hre.deployConfig.systemConfigOwner,
hre.deployConfig.gasPriceOracleOverhead,
hre.deployConfig.gasPriceOracleScalar,
batcherHash,
hre.deployConfig.l2GenesisBlockGasLimit,
],
postDeployAction: async (contract) => {
await assertContractVariable(
contract,
'owner',
hre.deployConfig.systemConfigOwner
)
await assertContractVariable(
contract,
'overhead',
hre.deployConfig.gasPriceOracleOverhead
)
await assertContractVariable(
contract,
'scalar',
hre.deployConfig.gasPriceOracleScalar
)
await assertContractVariable(
contract,
'batcherHash',
batcherHash.toLowerCase()
)
},
})
}
deployFn.tags = ['SystemConfigImpl', 'fresh', 'migration']
export default deployFn
...@@ -46,6 +46,10 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -46,6 +46,10 @@ const deployFn: DeployFunction = async (hre) => {
hre, hre,
'L1ERC721BridgeProxy' 'L1ERC721BridgeProxy'
), ),
systemConfigProxy: await getDeploymentAddress(
hre,
'SystemConfigProxy'
),
}, },
implementationAddressConfig: { implementationAddressConfig: {
l2OutputOracleImpl: await getDeploymentAddress(hre, 'L2OutputOracle'), l2OutputOracleImpl: await getDeploymentAddress(hre, 'L2OutputOracle'),
...@@ -64,6 +68,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -64,6 +68,7 @@ const deployFn: DeployFunction = async (hre) => {
), ),
l1ERC721BridgeImpl: await getDeploymentAddress(hre, 'L1ERC721Bridge'), l1ERC721BridgeImpl: await getDeploymentAddress(hre, 'L1ERC721Bridge'),
portalSenderImpl: await getDeploymentAddress(hre, 'PortalSender'), portalSenderImpl: await getDeploymentAddress(hre, 'PortalSender'),
systemConfigImpl: await getDeploymentAddress(hre, 'SystemConfig'),
}, },
l2OutputOracleConfig: { l2OutputOracleConfig: {
l2OutputOracleGenesisL2Output: l2OutputOracleGenesisL2Output:
...@@ -71,6 +76,16 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -71,6 +76,16 @@ const deployFn: DeployFunction = async (hre) => {
l2OutputOracleProposer: hre.deployConfig.l2OutputOracleProposer, l2OutputOracleProposer: hre.deployConfig.l2OutputOracleProposer,
l2OutputOracleOwner: hre.deployConfig.l2OutputOracleOwner, l2OutputOracleOwner: hre.deployConfig.l2OutputOracleOwner,
}, },
systemConfigConfig: {
owner: hre.deployConfig.systemConfigOwner,
overhead: hre.deployConfig.gasPriceOracleOverhead,
scalar: hre.deployConfig.gasPriceOracleDecimals,
batcherHash: hre.ethers.utils.hexZeroPad(
hre.deployConfig.batchSenderAddress,
32
),
gasLimit: hre.deployConfig.l2GenesisBlockGasLimit,
},
}, },
], ],
postDeployAction: async () => { postDeployAction: async () => {
......
...@@ -81,6 +81,10 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -81,6 +81,10 @@ const deployFn: DeployFunction = async (hre) => {
hre, hre,
'L1ERC721BridgeProxy' 'L1ERC721BridgeProxy'
), ),
systemConfigProxy: await getDeploymentAddress(
hre,
'SystemConfigProxy'
),
}, },
implementationAddressConfig: { implementationAddressConfig: {
l2OutputOracleImpl: await getDeploymentAddress(hre, 'L2OutputOracle'), l2OutputOracleImpl: await getDeploymentAddress(hre, 'L2OutputOracle'),
...@@ -99,6 +103,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -99,6 +103,7 @@ const deployFn: DeployFunction = async (hre) => {
), ),
l1ERC721BridgeImpl: await getDeploymentAddress(hre, 'L1ERC721Bridge'), l1ERC721BridgeImpl: await getDeploymentAddress(hre, 'L1ERC721Bridge'),
portalSenderImpl: await getDeploymentAddress(hre, 'PortalSender'), portalSenderImpl: await getDeploymentAddress(hre, 'PortalSender'),
systemConfigImpl: await getDeploymentAddress(hre, 'SystemConfig'),
}, },
l2OutputOracleConfig: { l2OutputOracleConfig: {
l2OutputOracleGenesisL2Output: l2OutputOracleGenesisL2Output:
...@@ -106,6 +111,16 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -106,6 +111,16 @@ const deployFn: DeployFunction = async (hre) => {
l2OutputOracleProposer: hre.deployConfig.l2OutputOracleProposer, l2OutputOracleProposer: hre.deployConfig.l2OutputOracleProposer,
l2OutputOracleOwner: hre.deployConfig.l2OutputOracleOwner, l2OutputOracleOwner: hre.deployConfig.l2OutputOracleOwner,
}, },
systemConfigConfig: {
owner: hre.deployConfig.systemConfigOwner,
overhead: hre.deployConfig.gasPriceOracleOverhead,
scalar: hre.deployConfig.gasPriceOracleDecimals,
batcherHash: hre.ethers.utils.hexZeroPad(
hre.deployConfig.batchSenderAddress,
32
),
gasLimit: hre.deployConfig.l2GenesisBlockGasLimit,
},
}, },
], ],
postDeployAction: async () => { postDeployAction: async () => {
......
...@@ -116,7 +116,13 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -116,7 +116,13 @@ const deployFn: DeployFunction = async (hre) => {
hre, hre,
'Proxy__OVM_L1StandardBridge' 'Proxy__OVM_L1StandardBridge'
) )
if ((await L1StandardBridge.owner()) !== MigrationSystemDictator.address) { const getOwnerOpts = {
from: ethers.constants.AddressZero,
}
if (
(await L1StandardBridge.callStatic.getOwner(getOwnerOpts)) !==
MigrationSystemDictator.address
) {
if (isLiveDeployer) { if (isLiveDeployer) {
console.log( console.log(
`Transferring ownership of L1StandardBridge to the MigrationSystemDictator...` `Transferring ownership of L1StandardBridge to the MigrationSystemDictator...`
...@@ -135,7 +141,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -135,7 +141,7 @@ const deployFn: DeployFunction = async (hre) => {
) )
} }
await awaitCondition(async () => { await awaitCondition(async () => {
const owner = await L1StandardBridge.callStatic.getOwner() const owner = await L1StandardBridge.callStatic.getOwner(getOwnerOpts)
return owner === MigrationSystemDictator.address return owner === MigrationSystemDictator.address
}) })
} else { } else {
...@@ -152,7 +158,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -152,7 +158,7 @@ const deployFn: DeployFunction = async (hre) => {
await awaitCondition(async () => { await awaitCondition(async () => {
const step = await MigrationSystemDictator.currentStep() const step = await MigrationSystemDictator.currentStep()
return step.toNumber() === i + 1 return Number(step) === i + 1
}) })
} }
} }
......
...@@ -280,6 +280,14 @@ export const assertContractVariable = async ( ...@@ -280,6 +280,14 @@ export const assertContractVariable = async (
from: ethers.constants.AddressZero, from: ethers.constants.AddressZero,
}) })
if (ethers.utils.isAddress(expected)) {
assert(
actual.toLowerCase() === expected.toLowerCase(),
`[FATAL] ${variable} is ${actual} but should be ${expected}`
)
return
}
assert( assert(
actual === expected || (actual.eq && actual.eq(expected)), actual === expected || (actual.eq && actual.eq(expected)),
`[FATAL] ${variable} is ${actual} but should be ${expected}` `[FATAL] ${variable} is ${actual} but should be ${expected}`
......
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