Commit 4af29574 authored by Maurelian's avatar Maurelian Committed by Kelvin Fichter

refactor(contracts): Add libAddressManager config option

Also introduces a new function getLibAddressManager() which returns the
address based either on config or previous deployment.
Also remove renames deployAndRegister to deployAndPostAction, and modifies
its behavior accordingly.
parent a54158c2
......@@ -3,17 +3,15 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */
import {
deployAndRegister,
deployAndPostDeploy,
getDeployedContract,
getLibAddressManager,
} from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager'
)
const Lib_AddressManager = await getLibAddressManager(hre)
await deployAndRegister({
await deployAndPostDeploy({
hre,
name: 'ChainStorageContainer-CTC-batches',
contract: 'ChainStorageContainer',
......
......@@ -3,17 +3,15 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */
import {
deployAndRegister,
deployAndPostDeploy,
getDeployedContract,
getLibAddressManager,
} from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager'
)
const Lib_AddressManager = await getLibAddressManager(hre)
await deployAndRegister({
await deployAndPostDeploy({
hre,
name: 'ChainStorageContainer-SCC-batches',
contract: 'ChainStorageContainer',
......
......@@ -3,17 +3,15 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */
import {
deployAndRegister,
deployAndPostDeploy,
getDeployedContract,
getLibAddressManager,
} from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager'
)
const Lib_AddressManager = await getLibAddressManager(hre)
await deployAndRegister({
await deployAndPostDeploy({
hre,
name: 'CanonicalTransactionChain',
args: [
......
......@@ -3,17 +3,15 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */
import {
deployAndRegister,
deployAndPostDeploy,
getDeployedContract,
getLibAddressManager,
} from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager'
)
const Lib_AddressManager = await getLibAddressManager(hre)
await deployAndRegister({
await deployAndPostDeploy({
hre,
name: 'StateCommitmentChain',
args: [
......
......@@ -3,17 +3,15 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */
import {
deployAndRegister,
deployAndPostDeploy,
getDeployedContract,
getLibAddressManager,
} from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager'
)
const Lib_AddressManager = await getLibAddressManager(hre)
await deployAndRegister({
await deployAndPostDeploy({
hre,
name: 'BondManager',
args: [Lib_AddressManager.address],
......
......@@ -4,19 +4,16 @@ import { hexStringEquals } from '@eth-optimism/core-utils'
/* Imports: Internal */
import {
getDeployedContract,
deployAndRegister,
deployAndPostDeploy,
getLibAddressManager,
waitUntilTrue,
} from '../src/hardhat-deploy-ethers'
// todo: this implementation needs to also have a chugsplash proxy in front of it.
const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager'
)
const Lib_AddressManager = await getLibAddressManager(hre)
await deployAndRegister({
await deployAndPostDeploy({
hre,
name: 'OVM_L1CrossDomainMessenger',
contract: 'L1CrossDomainMessenger',
......
......@@ -4,19 +4,16 @@ import { hexStringEquals } from '@eth-optimism/core-utils'
/* Imports: Internal */
import {
getDeployedContract,
deployAndRegister,
deployAndPostDeploy,
getLibAddressManager,
waitUntilTrue,
} from '../src/hardhat-deploy-ethers'
// We need to skip this step, because we're keeping the existing proxy.
const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager'
)
const Lib_AddressManager = await getLibAddressManager(hre)
await deployAndRegister({
await deployAndPostDeploy({
hre,
name: 'Proxy__OVM_L1CrossDomainMessenger',
contract: 'Lib_ResolvedDelegateProxy',
......
......@@ -2,12 +2,12 @@
import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */
import { deployAndRegister } from '../src/hardhat-deploy-ethers'
import { deployAndPostDeploy } from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
await deployAndRegister({
await deployAndPostDeploy({
hre,
name: 'Proxy__OVM_L1StandardBridge',
contract: 'L1ChugSplashProxy',
......
......@@ -11,6 +11,7 @@ import {
} from '../src/contract-defs'
import {
getDeployedContract,
getLibAddressManager,
waitUntilTrue,
getAdvancedContract,
deployAndRegister,
......@@ -18,10 +19,7 @@ import {
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager'
)
const Lib_AddressManager = await getLibAddressManager(hre)
// Set up a reference to the proxy as if it were the L1StandardBridge contract.
const contract = await getDeployedContract(
......
/* Imports: External */
import { DeployFunction, DeploymentsExtension } from 'hardhat-deploy/dist/types'
/* Imports: Internal */
import {
deployAndPostDeploy,
getDeployedContract,
getLibAddressManager,
} from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getLibAddressManager(hre)
const names = [
'ChainStorageContainer-CTC-batches',
'ChainStorageContainer-SCC-batches',
'CanonicalTransactionChain',
'StateCommitmentChain',
'BondManager',
'OVM_L1CrossDomainMessenger',
'Proxy__L1CrossDomainMessenger',
'Proxy__L1StandardBridge',
'OVM_Proposer',
]
const addresses = await Promise.all(
names.map(async (n) => {
return (await getDeployedContract(hre, n)).address
})
)
await deployAndPostDeploy({
hre,
name: 'AddressSetter',
args: [
Lib_AddressManager.address,
(hre as any).deployConfig.ovmAddressManagerOwner,
names,
addresses,
],
})
}
deployFn.tags = ['AddressSetter', 'upgrade']
export default deployFn
/* Imports: External */
import { sleep } from '@eth-optimism/core-utils'
import { DeployFunction } from 'hardhat-deploy/dist/types'
import {
defaultHardhatNetworkHdAccountsConfigParams,
defaultHardhatNetworkParams,
} from 'hardhat/internal/core/config/default-config'
import { normalizeHardhatNetworkAccountsConfig } from 'hardhat/internal/core/providers/util'
/* Imports: Internal */
import { getDeployedContract } from '../src/hardhat-deploy-ethers'
// This is a TEMPORARY way to fund the default hardhat accounts on L2. The better way to do this is
// to make a modification to hardhat-ovm. However, I don't have the time right now to figure the
// details of how to make that work cleanly. This is fine in the meantime.
const deployFn: DeployFunction = async (hre) => {
// Only execute this step if we're on the hardhat chain ID.
const { chainId } = await hre.ethers.provider.getNetwork()
if (chainId === defaultHardhatNetworkParams.chainId) {
const L1StandardBridge = await getDeployedContract(
hre,
'Proxy__L1StandardBridge',
{
iface: 'L1StandardBridge',
}
)
// Default has 20 accounts but we restrict to 20 accounts manually as well just to prevent
// future problems if the number of default accounts increases for whatever reason.
const accounts = normalizeHardhatNetworkAccountsConfig(
defaultHardhatNetworkHdAccountsConfigParams
).slice(0, 20)
// Fund the accounts in parallel to speed things up.
await Promise.all(
accounts.map(async (account, index) => {
// Add a sleep here to avoid any potential issues with spamming hardhat. Not sure if this
// is strictly necessary but it can't hurt.
await sleep(200 * index)
const wallet = new hre.ethers.Wallet(
account.privateKey,
hre.ethers.provider
)
const balance = await wallet.getBalance()
const depositAmount = balance.div(2) // Deposit half of the wallet's balance into L2.
await L1StandardBridge.connect(wallet).depositETH(8_000_000, '0x', {
value: depositAmount,
gasLimit: 2_000_000, // Idk, gas estimation was broken and this fixes it.
})
console.log(
`✓ Funded ${wallet.address} on L2 with ${hre.ethers.utils.formatEther(
depositAmount
)} ETH`
)
})
)
}
}
deployFn.tags = ['fund-accounts']
export default deployFn
......@@ -25,41 +25,7 @@ export const waitUntilTrue = async (
}
}
export const registerAddress = async ({
hre,
name,
address,
}): Promise<void> => {
// TODO: Cache these 2 across calls?
const { deployer } = await hre.getNamedAccounts()
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager',
{
signerOrProvider: deployer,
}
)
const currentAddress = await Lib_AddressManager.getAddress(name)
if (address === currentAddress) {
console.log(
`✓ Not registering address for ${name} because it's already been correctly registered`
)
return
}
console.log(`Registering address for ${name} to ${address}...`)
await Lib_AddressManager.setAddress(name, address)
console.log(`Waiting for registration to reflect on-chain...`)
await waitUntilTrue(async () => {
return hexStringEquals(await Lib_AddressManager.getAddress(name), address)
})
console.log(`✓ Registered address for ${name}`)
}
export const deployAndRegister = async ({
export const deployAndPostDeploy = async ({
hre,
name,
args,
......@@ -102,12 +68,6 @@ export const deployAndRegister = async ({
})
)
}
await registerAddress({
hre,
name,
address: result.address,
})
}
}
......@@ -288,3 +248,15 @@ export const getContractFromArtifact = async (
// Large balance to fund accounts with.
export const BIG_BALANCE = ethers.BigNumber.from(`0xFFFFFFFFFFFFFFFFFFFF`)
export const getLibAddressManager = async (hre: any): Promise<Contract> => {
const factory = await hre.ethers.getContractFactory('Lib_AddressManager')
const iface = factory.interface
// try to get the address from the config options
const addr = (hre as any).deployConfig.libAddressManager
if (hre.ethers.utils.isAddress(addr)) {
return new Contract(addr, iface)
} else {
// if an address was not provided, a new manager must have been deployed
return getDeployedContract(hre, 'Lib_AddressManager')
}
}
......@@ -60,6 +60,12 @@ task('deploy')
undefined,
types.string
)
.addOptionalParam(
'libAddressManager',
'Address of the Lib_AddressManager, for use in a deployment which is keeping the existing contract.',
undefined,
types.string
)
.addOptionalParam(
'ovmAddressManagerOwner',
'Address that will own the Lib_AddressManager. Must be provided or this deployment will fail.',
......@@ -97,6 +103,24 @@ task('deploy')
validateAddressArg('ovmProposerAddress')
validateAddressArg('ovmAddressManagerOwner')
const hasAddressManagerTag = args.tags
.split(',')
.includes('Lib_AddressManager')
try {
validateAddressArg('libAddressManager')
if (hasAddressManagerTag) {
throw new Error(
'cannot deploy a new Lib_AddressManager if the address of an existing one is provided'
)
}
} catch (error) {
if (!hasAddressManagerTag) {
throw new Error(
'must either deploy a new Lib_AddressManager, or provide the address for an existing one'
)
}
}
hre.deployConfig = args
return runSuper(args)
})
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