Commit b3b97959 authored by Maurelian's avatar Maurelian Committed by Kelvin Fichter

fix(contracts): Get artifacts from deployments

Rather than adding additional config args to npx hardhat deploy
parent 6bc84976
...@@ -4,11 +4,11 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' ...@@ -4,11 +4,11 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */ /* Imports: Internal */
import { import {
deployAndPostDeploy, deployAndPostDeploy,
getLiveContract, getContractFromArtifact,
} from '../src/hardhat-deploy-ethers' } from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getLiveContract(hre, 'Lib_AddressManager') const Lib_AddressManager = await getContractFromArtifact(hre, 'Lib_AddressManager')
await deployAndPostDeploy({ await deployAndPostDeploy({
hre, hre,
......
...@@ -4,11 +4,11 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' ...@@ -4,11 +4,11 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */ /* Imports: Internal */
import { import {
deployAndPostDeploy, deployAndPostDeploy,
getLiveContract, getContractFromArtifact,
} from '../src/hardhat-deploy-ethers' } from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getLiveContract(hre, 'Lib_AddressManager') const Lib_AddressManager = await getContractFromArtifact(hre, 'Lib_AddressManager')
await deployAndPostDeploy({ await deployAndPostDeploy({
hre, hre,
......
...@@ -4,11 +4,11 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' ...@@ -4,11 +4,11 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */ /* Imports: Internal */
import { import {
deployAndPostDeploy, deployAndPostDeploy,
getLiveContract, getContractFromArtifact,
} from '../src/hardhat-deploy-ethers' } from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getLiveContract(hre, 'Lib_AddressManager') const Lib_AddressManager = await getContractFromArtifact(hre, 'Lib_AddressManager')
await deployAndPostDeploy({ await deployAndPostDeploy({
hre, hre,
......
...@@ -4,11 +4,11 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' ...@@ -4,11 +4,11 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */ /* Imports: Internal */
import { import {
deployAndPostDeploy, deployAndPostDeploy,
getLiveContract, getContractFromArtifact,
} from '../src/hardhat-deploy-ethers' } from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getLiveContract(hre, 'Lib_AddressManager') const Lib_AddressManager = await getContractFromArtifact(hre, 'Lib_AddressManager')
await deployAndPostDeploy({ await deployAndPostDeploy({
hre, hre,
......
...@@ -4,11 +4,11 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' ...@@ -4,11 +4,11 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */ /* Imports: Internal */
import { import {
deployAndPostDeploy, deployAndPostDeploy,
getLiveContract, getContractFromArtifact,
} from '../src/hardhat-deploy-ethers' } from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getLiveContract(hre, 'Lib_AddressManager') const Lib_AddressManager = await getContractFromArtifact(hre, 'Lib_AddressManager')
await deployAndPostDeploy({ await deployAndPostDeploy({
hre, hre,
......
...@@ -5,12 +5,12 @@ import { hexStringEquals } from '@eth-optimism/core-utils' ...@@ -5,12 +5,12 @@ import { hexStringEquals } from '@eth-optimism/core-utils'
/* Imports: Internal */ /* Imports: Internal */
import { import {
deployAndPostDeploy, deployAndPostDeploy,
getLiveContract, getContractFromArtifact,
waitUntilTrue, waitUntilTrue,
} from '../src/hardhat-deploy-ethers' } from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getLiveContract(hre, 'Lib_AddressManager') const Lib_AddressManager = await getContractFromArtifact(hre, 'Lib_AddressManager')
await deployAndPostDeploy({ await deployAndPostDeploy({
hre, hre,
......
...@@ -5,12 +5,12 @@ import { hexStringEquals } from '@eth-optimism/core-utils' ...@@ -5,12 +5,12 @@ import { hexStringEquals } from '@eth-optimism/core-utils'
/* Imports: Internal */ /* Imports: Internal */
import { import {
deployAndPostDeploy, deployAndPostDeploy,
getLiveContract, getContractFromArtifact,
waitUntilTrue, waitUntilTrue,
} from '../src/hardhat-deploy-ethers' } from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getLiveContract(hre, 'Lib_AddressManager') const Lib_AddressManager = await getContractFromArtifact(hre, 'Lib_AddressManager')
// todo: this fails when trying to do a fresh deploy, because Lib_ResolvedDelegateProxy // todo: this fails when trying to do a fresh deploy, because Lib_ResolvedDelegateProxy
// requires that the implementation has already been set in the Address Manager. // requires that the implementation has already been set in the Address Manager.
......
...@@ -10,7 +10,7 @@ import { ...@@ -10,7 +10,7 @@ import {
getContractDefinition, getContractDefinition,
} from '../src/contract-defs' } from '../src/contract-defs'
import { import {
getLiveContract, getContractFromArtifact,
waitUntilTrue, waitUntilTrue,
getAdvancedContract, getAdvancedContract,
deployAndPostDeploy, deployAndPostDeploy,
...@@ -20,7 +20,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -20,7 +20,7 @@ const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts() const { deployer } = await hre.getNamedAccounts()
// Set up a reference to the proxy as if it were the L1StandardBridge contract. // Set up a reference to the proxy as if it were the L1StandardBridge contract.
const contract = await getLiveContract(hre, 'Proxy__OVM_L1StandardBridge', { const contract = await getContractFromArtifact(hre, 'Proxy__OVM_L1StandardBridge', {
iface: 'L1StandardBridge', iface: 'L1StandardBridge',
signerOrProvider: deployer, signerOrProvider: deployer,
}) })
...@@ -62,7 +62,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -62,7 +62,7 @@ const deployFn: DeployFunction = async (hre) => {
// Next we need to set the `messenger` address by executing a setStorage operation. We'll // Next we need to set the `messenger` address by executing a setStorage operation. We'll
// check that this operation was correctly executed by calling `messenger()` and checking // check that this operation was correctly executed by calling `messenger()` and checking
// that the result matches the value we initialized. // that the result matches the value we initialized.
const l1CrossDomainMessenger = await getLiveContract( const l1CrossDomainMessenger = await getContractFromArtifact(
hre, hre,
'Proxy__OVM_L1CrossDomainMessenger' 'Proxy__OVM_L1CrossDomainMessenger'
) )
......
...@@ -5,12 +5,12 @@ import { hexStringEquals } from '@eth-optimism/core-utils' ...@@ -5,12 +5,12 @@ import { hexStringEquals } from '@eth-optimism/core-utils'
/* Imports: Internal */ /* Imports: Internal */
import { import {
deployAndPostDeploy, deployAndPostDeploy,
getLiveContract, getContractFromArtifact,
} from '../src/hardhat-deploy-ethers' } from '../src/hardhat-deploy-ethers'
import { predeploys } from '../src/predeploys' import { predeploys } from '../src/predeploys'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getLiveContract(hre, 'Lib_AddressManager') const Lib_AddressManager = await getContractFromArtifact(hre, 'Lib_AddressManager')
// ToDo: Clean up the method of mapping names to addresses esp. // ToDo: Clean up the method of mapping names to addresses esp.
// There's probably a more functional way to generate an object or something. // There's probably a more functional way to generate an object or something.
...@@ -32,7 +32,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -32,7 +32,7 @@ const deployFn: DeployFunction = async (hre) => {
allContractNames.map(async (name) => { allContractNames.map(async (name) => {
return { return {
name, name,
address: (await getLiveContract(hre, name)).address, address: (await getContractFromArtifact(hre, name)).address,
} }
}) })
) )
......
...@@ -4,14 +4,14 @@ import { ethers } from 'hardhat' ...@@ -4,14 +4,14 @@ import { ethers } from 'hardhat'
import { DeployFunction } from 'hardhat-deploy/dist/types' import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */ /* Imports: Internal */
import { getLiveContract, waitUntilTrue } from '../src/hardhat-deploy-ethers' import { getContractFromArtifact, waitUntilTrue } from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts() const { deployer } = await hre.getNamedAccounts()
const addressDictator = await getLiveContract(hre, 'AddressDictator', { const addressDictator = await getContractFromArtifact(hre, 'AddressDictator', {
signerOrProvider: deployer, signerOrProvider: deployer,
}) })
const libAddressManager = await getLiveContract(hre, 'Lib_AddressManager') const libAddressManager = await getContractFromArtifact(hre, 'Lib_AddressManager')
const namedAddresses = await addressDictator.getNamedAddresses() const namedAddresses = await addressDictator.getNamedAddresses()
const finalOwner = await addressDictator.finalOwner() const finalOwner = await addressDictator.finalOwner()
let currentOwner = await libAddressManager.owner() let currentOwner = await libAddressManager.owner()
......
...@@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' ...@@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
import { hexStringEquals } from '@eth-optimism/core-utils' import { hexStringEquals } from '@eth-optimism/core-utils'
/* Imports: Internal */ /* Imports: Internal */
import { getLiveContract, waitUntilTrue } from '../src/hardhat-deploy-ethers' import { getContractFromArtifact, waitUntilTrue } from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts() const { deployer } = await hre.getNamedAccounts()
...@@ -11,7 +11,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -11,7 +11,7 @@ const deployFn: DeployFunction = async (hre) => {
// There is a risk that on a fresh deployment we could get front-run, // There is a risk that on a fresh deployment we could get front-run,
// and the Proxy would be bricked. But that feels unlikely, and we can recover from it. // and the Proxy would be bricked. But that feels unlikely, and we can recover from it.
console.log(`Initializing Proxy__L1CrossDomainMessenger...`) console.log(`Initializing Proxy__L1CrossDomainMessenger...`)
const proxy = await getLiveContract( const proxy = await getContractFromArtifact(
hre, hre,
'Proxy__OVM_L1CrossDomainMessenger', 'Proxy__OVM_L1CrossDomainMessenger',
{ {
...@@ -19,7 +19,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -19,7 +19,7 @@ const deployFn: DeployFunction = async (hre) => {
signerOrProvider: deployer, signerOrProvider: deployer,
} }
) )
const libAddressManager = await getLiveContract(hre, 'Lib_AddressManager') const libAddressManager = await getContractFromArtifact(hre, 'Lib_AddressManager')
await proxy.initialize(libAddressManager.address) await proxy.initialize(libAddressManager.address)
console.log(`Checking that contract was correctly initialized...`) console.log(`Checking that contract was correctly initialized...`)
......
...@@ -3,11 +3,11 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' ...@@ -3,11 +3,11 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
import { hexStringEquals } from '@eth-optimism/core-utils' import { hexStringEquals } from '@eth-optimism/core-utils'
/* Imports: Internal */ /* Imports: Internal */
import { getLiveContract, waitUntilTrue } from '../src/hardhat-deploy-ethers' import { getContractFromArtifact, waitUntilTrue } from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts() const { deployer } = await hre.getNamedAccounts()
const Lib_AddressManager = await getLiveContract(hre, 'Lib_AddressManager', { const Lib_AddressManager = await getContractFromArtifact(hre, 'Lib_AddressManager', {
signerOrProvider: deployer, signerOrProvider: deployer,
}) })
......
...@@ -8,7 +8,7 @@ import { ...@@ -8,7 +8,7 @@ import {
import { normalizeHardhatNetworkAccountsConfig } from 'hardhat/internal/core/providers/util' import { normalizeHardhatNetworkAccountsConfig } from 'hardhat/internal/core/providers/util'
/* Imports: Internal */ /* Imports: Internal */
import { getLiveContract } from '../src/hardhat-deploy-ethers' import { getContractFromArtifact } 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 // 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 // to make a modification to hardhat-ovm. However, I don't have the time right now to figure the
...@@ -17,7 +17,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -17,7 +17,7 @@ const deployFn: DeployFunction = async (hre) => {
// Only execute this step if we're on the hardhat chain ID. // Only execute this step if we're on the hardhat chain ID.
const { chainId } = await hre.ethers.provider.getNetwork() const { chainId } = await hre.ethers.provider.getNetwork()
if (chainId === defaultHardhatNetworkParams.chainId) { if (chainId === defaultHardhatNetworkParams.chainId) {
const L1StandardBridge = await getLiveContract( const L1StandardBridge = await getContractFromArtifact(
hre, hre,
'Proxy__OVM_L1StandardBridge', 'Proxy__OVM_L1StandardBridge',
{ {
......
...@@ -136,57 +136,6 @@ export const getAdvancedContract = (opts: { ...@@ -136,57 +136,6 @@ export const getAdvancedContract = (opts: {
return contract return contract
} }
// A map from contract names to config names which can be passed as arguments to hardhat deploy
const configNames = {
Lib_AddressManager: 'libAddressManager',
Proxy__L1CrossDomainMessenger: 'proxyL1CrossDomainMessenger',
Proxy__L1StandardBridge: 'proxyL1StandardBridge',
}
export const getLiveContract = async (
hre: any,
name: string,
options: {
iface?: string
signerOrProvider?: Signer | Provider | string
} = {}
): Promise<Contract> => {
// First check to see if the contract is being reused in an upgrade, rather than freshly deployed.
// If so, then a valid address would have been provided for one of the 3 contracts in configNames.
const addr = (hre as any).deployConfig[configNames[name]]
if (hre.ethers.utils.isAddress(addr)) {
// Get the interface by name, unless an override was requested via the iface option
const factory = await hre.ethers.getContractFactory(options.iface || name)
return new Contract(addr, factory.interface)
}
// Otherwise, look for a previously deployed contract.
const deployed = await hre.deployments.get(name)
await hre.ethers.provider.waitForTransaction(deployed.receipt.transactionHash)
// Get the deployed contract's interface.
let iface = new hre.ethers.utils.Interface(deployed.abi)
// Override with optional iface name if requested.
if (options.iface) {
const factory = await hre.ethers.getContractFactory(options.iface)
iface = factory.interface
}
let signerOrProvider: Signer | Provider = hre.ethers.provider
if (options.signerOrProvider) {
if (typeof options.signerOrProvider === 'string') {
signerOrProvider = hre.ethers.provider.getSigner(options.signerOrProvider)
} else {
signerOrProvider = options.signerOrProvider
}
}
return getAdvancedContract({
hre,
contract: new Contract(deployed.address, iface, signerOrProvider),
})
}
export const fundAccount = async ( export const fundAccount = async (
hre: any, hre: any,
address: string, address: string,
...@@ -250,15 +199,38 @@ export const sendImpersonatedTx = async (opts: { ...@@ -250,15 +199,38 @@ export const sendImpersonatedTx = async (opts: {
export const getContractFromArtifact = async ( export const getContractFromArtifact = async (
hre: any, hre: any,
name: string name: string,
options: {
iface?: string
signerOrProvider?: Signer | Provider | string
} = {}
): Promise<ethers.Contract> => { ): Promise<ethers.Contract> => {
const artifact = await hre.deployments.get(name) const artifact = await hre.deployments.get(name)
await hre.ethers.provider.waitForTransaction(artifact.receipt.transactionHash)
// Get the deployed contract's interface.
let iface = new hre.ethers.utils.Interface(artifact.abi)
// Override with optional iface name if requested.
if (options.iface) {
const factory = await hre.ethers.getContractFactory(options.iface)
iface = factory.interface
}
let signerOrProvider: Signer | Provider = hre.ethers.provider
if (options.signerOrProvider) {
if (typeof options.signerOrProvider === 'string') {
signerOrProvider = hre.ethers.provider.getSigner(options.signerOrProvider)
} else {
signerOrProvider = options.signerOrProvider
}
}
return getAdvancedContract({ return getAdvancedContract({
hre, hre,
contract: new hre.ethers.Contract( contract: new hre.ethers.Contract(
artifact.address, artifact.address,
artifact.abi, iface,
hre.ethers.provider signerOrProvider
), ),
}) })
} }
......
...@@ -118,41 +118,6 @@ task('deploy') ...@@ -118,41 +118,6 @@ task('deploy')
validateAddressArg('ovmProposerAddress') validateAddressArg('ovmProposerAddress')
validateAddressArg('ovmAddressManagerOwner') validateAddressArg('ovmAddressManagerOwner')
// Validate potentially conflicting arguments
// When are argName is provided, it indicates an address that will be reused in this deployment.
// When a tagName is provided, it indicates that a new contract will be deployed.
const validateArgOrTag = (argName: string, tagName: string) => {
// The 'fresh' tag tells us that a new copy of each contract will be deployed.
const hasTag = args.tags.includes(tagName)
// Ensure that an arg and tag were NOT BOTH provided for a given contract
if (hasTag && ethers.utils.isAddress(args[argName])) {
throw new Error(
`cannot deploy a new ${tagName} if the address of an existing one is provided`
)
}
// Ensure that either a valid address is provided OR that we deploy a new one.
try {
validateAddressArg(argName)
console.log(
`Running deployments with the existing ${tagName} at ${args[argName]}`
)
} catch (error) {
if (!hasTag) {
throw new Error(
`${error.message} \nmust either deploy a new ${tagName}, or provide the address for an existing one`
)
}
console.log(`Running deployments with a new ${tagName}`)
}
}
validateArgOrTag('libAddressManager', 'Lib_AddressManager')
validateArgOrTag(
'proxyL1CrossDomainMessenger',
'Proxy__OVM_L1CrossDomainMessenger'
)
validateArgOrTag('proxyL1StandardBridge', 'Proxy__OVM_L1StandardBridge')
hre.deployConfig = args hre.deployConfig = args
return runSuper(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