UNPKG

@hyperlane-xyz/core

Version:

Core solidity contracts for Hyperlane

204 lines (187 loc) 6.4 kB
import assert from 'assert' import { ethers, BigNumber } 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 { getContractsFromArtifacts, getDeploymentAddress, } from '../src/deploy-utils' const deployFn: DeployFunction = async (hre) => { const { deployer } = await hre.getNamedAccounts() // Load the contracts we need to interact with. const [ SystemDictator, SystemDictatorProxy, SystemDictatorProxyWithSigner, SystemDictatorImpl, ] = await getContractsFromArtifacts(hre, [ { name: 'SystemDictatorProxy', iface: 'SystemDictator', signerOrProvider: deployer, }, { name: 'SystemDictatorProxy', }, { name: 'SystemDictatorProxy', signerOrProvider: deployer, }, { name: 'SystemDictator', signerOrProvider: deployer, }, ]) // Load the dictator configuration. const config = { globalConfig: { proxyAdmin: await getDeploymentAddress(hre, 'ProxyAdmin'), controller: hre.deployConfig.controller, finalOwner: hre.deployConfig.finalSystemOwner, addressManager: await getDeploymentAddress(hre, 'Lib_AddressManager'), }, proxyAddressConfig: { l2OutputOracleProxy: await getDeploymentAddress( hre, 'L2OutputOracleProxy' ), optimismPortalProxy: await getDeploymentAddress( hre, 'OptimismPortalProxy' ), l1CrossDomainMessengerProxy: await getDeploymentAddress( hre, 'Proxy__OVM_L1CrossDomainMessenger' ), l1StandardBridgeProxy: await getDeploymentAddress( hre, 'Proxy__OVM_L1StandardBridge' ), optimismMintableERC20FactoryProxy: await getDeploymentAddress( hre, 'OptimismMintableERC20FactoryProxy' ), l1ERC721BridgeProxy: await getDeploymentAddress( hre, 'L1ERC721BridgeProxy' ), systemConfigProxy: await getDeploymentAddress(hre, 'SystemConfigProxy'), }, implementationAddressConfig: { l2OutputOracleImpl: await getDeploymentAddress(hre, 'L2OutputOracle'), optimismPortalImpl: await getDeploymentAddress(hre, 'OptimismPortal'), l1CrossDomainMessengerImpl: await getDeploymentAddress( hre, 'L1CrossDomainMessenger' ), l1StandardBridgeImpl: await getDeploymentAddress(hre, 'L1StandardBridge'), optimismMintableERC20FactoryImpl: await getDeploymentAddress( hre, 'OptimismMintableERC20Factory' ), l1ERC721BridgeImpl: await getDeploymentAddress(hre, 'L1ERC721Bridge'), portalSenderImpl: await getDeploymentAddress(hre, 'PortalSender'), systemConfigImpl: await getDeploymentAddress(hre, 'SystemConfig'), }, systemConfigConfig: { owner: hre.deployConfig.finalSystemOwner, overhead: hre.deployConfig.gasPriceOracleOverhead, scalar: hre.deployConfig.gasPriceOracleScalar, batcherHash: hre.ethers.utils.hexZeroPad( hre.deployConfig.batchSenderAddress, 32 ), gasLimit: hre.deployConfig.l2GenesisBlockGasLimit, unsafeBlockSigner: hre.deployConfig.p2pSequencerAddress, // The resource config is not exposed to the end user // to simplify deploy config. It may be introduced in the future. resourceConfig: { maxResourceLimit: 20_000_000, elasticityMultiplier: 10, baseFeeMaxChangeDenominator: 8, minimumBaseFee: ethers.utils.parseUnits('1', 'gwei'), systemTxMaxGas: 1_000_000, maximumBaseFee: BigNumber.from( '0xffffffffffffffffffffffffffffffff' ).toString(), }, }, } // Update the implementation if necessary. if ( (await SystemDictatorProxy.callStatic.implementation({ from: ethers.constants.AddressZero, })) !== SystemDictatorImpl.address ) { console.log('Upgrading the SystemDictator proxy...') // Upgrade and initialize the proxy. await SystemDictatorProxyWithSigner.upgradeToAndCall( SystemDictatorImpl.address, SystemDictatorImpl.interface.encodeFunctionData('initialize', [config]) ) // Wait for the transaction to execute properly. await awaitCondition( async () => { return ( (await SystemDictatorProxy.callStatic.implementation({ from: ethers.constants.AddressZero, })) === SystemDictatorImpl.address ) }, 30000, 1000 ) // Verify that the contract was initialized correctly. const dictatorConfig = await SystemDictator.config() for (const [outerConfigKey, outerConfigValue] of Object.entries(config)) { for (const [innerConfigKey, innerConfigValue] of Object.entries( outerConfigValue )) { let have = dictatorConfig[outerConfigKey][innerConfigKey] let want = innerConfigValue as any if (ethers.utils.isAddress(want)) { want = want.toLowerCase() have = have.toLowerCase() } else if (typeof want === 'number') { want = ethers.BigNumber.from(want) have = ethers.BigNumber.from(have) assert( want.eq(have), `incorrect config for ${outerConfigKey}.${innerConfigKey}. Want: ${want}, have: ${have}` ) return } assert( want === have, `incorrect config for ${outerConfigKey}.${innerConfigKey}. Want: ${want}, have: ${have}` ) } } } // Update the owner if necessary. if ( (await SystemDictatorProxy.callStatic.admin({ from: ethers.constants.AddressZero, })) !== hre.deployConfig.controller ) { console.log('Transferring ownership of the SystemDictator proxy...') // Transfer ownership to the controller address. await SystemDictatorProxyWithSigner.changeAdmin(hre.deployConfig.controller) // Wait for the transaction to execute properly. await awaitCondition( async () => { return ( (await SystemDictatorProxy.callStatic.admin({ from: ethers.constants.AddressZero, })) === hre.deployConfig.controller ) }, 30000, 1000 ) } } deployFn.tags = ['SystemDictatorImpl', 'setup', 'l1'] export default deployFn