diff --git a/.changeset/clean-buttons-think.md b/.changeset/clean-buttons-think.md new file mode 100644 index 0000000000000..1498e6f2b4e1e --- /dev/null +++ b/.changeset/clean-buttons-think.md @@ -0,0 +1,5 @@ +--- +'@eth-optimism/contracts': patch +--- + +Run etherscan verification after each contract is deployed. diff --git a/packages/contracts/deploy/002-OVM_ChainStorageContainer_ctc_batches.deploy.ts b/packages/contracts/deploy/002-OVM_ChainStorageContainer_ctc_batches.deploy.ts index e66c361167824..37b87742bd558 100644 --- a/packages/contracts/deploy/002-OVM_ChainStorageContainer_ctc_batches.deploy.ts +++ b/packages/contracts/deploy/002-OVM_ChainStorageContainer_ctc_batches.deploy.ts @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' /* Imports: Internal */ import { - deployAndPostDeploy, + deployAndVerifyAndThen, getContractFromArtifact, } from '../src/hardhat-deploy-ethers' @@ -13,7 +13,7 @@ const deployFn: DeployFunction = async (hre) => { 'Lib_AddressManager' ) - await deployAndPostDeploy({ + await deployAndVerifyAndThen({ hre, name: 'ChainStorageContainer-CTC-batches', contract: 'ChainStorageContainer', diff --git a/packages/contracts/deploy/003-OVM_ChainStorageContainer_scc_batches.deploy.ts b/packages/contracts/deploy/003-OVM_ChainStorageContainer_scc_batches.deploy.ts index b20f85e4ecd93..2dae823cd0496 100644 --- a/packages/contracts/deploy/003-OVM_ChainStorageContainer_scc_batches.deploy.ts +++ b/packages/contracts/deploy/003-OVM_ChainStorageContainer_scc_batches.deploy.ts @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' /* Imports: Internal */ import { - deployAndPostDeploy, + deployAndVerifyAndThen, getContractFromArtifact, } from '../src/hardhat-deploy-ethers' @@ -13,7 +13,7 @@ const deployFn: DeployFunction = async (hre) => { 'Lib_AddressManager' ) - await deployAndPostDeploy({ + await deployAndVerifyAndThen({ hre, name: 'ChainStorageContainer-SCC-batches', contract: 'ChainStorageContainer', diff --git a/packages/contracts/deploy/004-OVM_CanonicalTransactionChain.deploy.ts b/packages/contracts/deploy/004-OVM_CanonicalTransactionChain.deploy.ts index b2171d1440280..679790ccaac9d 100644 --- a/packages/contracts/deploy/004-OVM_CanonicalTransactionChain.deploy.ts +++ b/packages/contracts/deploy/004-OVM_CanonicalTransactionChain.deploy.ts @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' /* Imports: Internal */ import { - deployAndPostDeploy, + deployAndVerifyAndThen, getContractFromArtifact, } from '../src/hardhat-deploy-ethers' @@ -13,7 +13,7 @@ const deployFn: DeployFunction = async (hre) => { 'Lib_AddressManager' ) - await deployAndPostDeploy({ + await deployAndVerifyAndThen({ hre, name: 'CanonicalTransactionChain', args: [ diff --git a/packages/contracts/deploy/005-OVM_StateCommitmentChain.deploy.ts b/packages/contracts/deploy/005-OVM_StateCommitmentChain.deploy.ts index 8b011eddf050c..983982f0cac41 100644 --- a/packages/contracts/deploy/005-OVM_StateCommitmentChain.deploy.ts +++ b/packages/contracts/deploy/005-OVM_StateCommitmentChain.deploy.ts @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' /* Imports: Internal */ import { - deployAndPostDeploy, + deployAndVerifyAndThen, getContractFromArtifact, } from '../src/hardhat-deploy-ethers' @@ -13,7 +13,7 @@ const deployFn: DeployFunction = async (hre) => { 'Lib_AddressManager' ) - await deployAndPostDeploy({ + await deployAndVerifyAndThen({ hre, name: 'StateCommitmentChain', args: [ diff --git a/packages/contracts/deploy/006-OVM_BondManager.deploy.ts b/packages/contracts/deploy/006-OVM_BondManager.deploy.ts index 5b447f492e41d..7ad66de62619c 100644 --- a/packages/contracts/deploy/006-OVM_BondManager.deploy.ts +++ b/packages/contracts/deploy/006-OVM_BondManager.deploy.ts @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' /* Imports: Internal */ import { - deployAndPostDeploy, + deployAndVerifyAndThen, getContractFromArtifact, } from '../src/hardhat-deploy-ethers' @@ -13,7 +13,7 @@ const deployFn: DeployFunction = async (hre) => { 'Lib_AddressManager' ) - await deployAndPostDeploy({ + await deployAndVerifyAndThen({ hre, name: 'BondManager', args: [Lib_AddressManager.address], diff --git a/packages/contracts/deploy/007-OVM_L1CrossDomainMessenger.deploy.ts b/packages/contracts/deploy/007-OVM_L1CrossDomainMessenger.deploy.ts index f4337683e8e23..37bdb485a2398 100644 --- a/packages/contracts/deploy/007-OVM_L1CrossDomainMessenger.deploy.ts +++ b/packages/contracts/deploy/007-OVM_L1CrossDomainMessenger.deploy.ts @@ -4,7 +4,7 @@ import { hexStringEquals, awaitCondition } from '@eth-optimism/core-utils' /* Imports: Internal */ import { - deployAndPostDeploy, + deployAndVerifyAndThen, getContractFromArtifact, } from '../src/hardhat-deploy-ethers' @@ -14,7 +14,7 @@ const deployFn: DeployFunction = async (hre) => { 'Lib_AddressManager' ) - await deployAndPostDeploy({ + await deployAndVerifyAndThen({ hre, name: 'OVM_L1CrossDomainMessenger', contract: 'L1CrossDomainMessenger', diff --git a/packages/contracts/deploy/008-Proxy__OVM_L1CrossDomainMessenger.deploy.ts b/packages/contracts/deploy/008-Proxy__OVM_L1CrossDomainMessenger.deploy.ts index 82a179256bd43..292dab8a4bcdb 100644 --- a/packages/contracts/deploy/008-Proxy__OVM_L1CrossDomainMessenger.deploy.ts +++ b/packages/contracts/deploy/008-Proxy__OVM_L1CrossDomainMessenger.deploy.ts @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' /* Imports: Internal */ import { - deployAndPostDeploy, + deployAndVerifyAndThen, getContractFromArtifact, } from '../src/hardhat-deploy-ethers' @@ -13,7 +13,7 @@ const deployFn: DeployFunction = async (hre) => { 'Lib_AddressManager' ) - await deployAndPostDeploy({ + await deployAndVerifyAndThen({ hre, name: 'Proxy__OVM_L1CrossDomainMessenger', contract: 'Lib_ResolvedDelegateProxy', diff --git a/packages/contracts/deploy/009-Proxy__OVM_L1StandardBridge.deploy.ts b/packages/contracts/deploy/009-Proxy__OVM_L1StandardBridge.deploy.ts index 96beb36e648d5..6c8b15176aed8 100644 --- a/packages/contracts/deploy/009-Proxy__OVM_L1StandardBridge.deploy.ts +++ b/packages/contracts/deploy/009-Proxy__OVM_L1StandardBridge.deploy.ts @@ -2,12 +2,12 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' /* Imports: Internal */ -import { deployAndPostDeploy } from '../src/hardhat-deploy-ethers' +import { deployAndVerifyAndThen } from '../src/hardhat-deploy-ethers' const deployFn: DeployFunction = async (hre) => { const { deployer } = await hre.getNamedAccounts() - await deployAndPostDeploy({ + await deployAndVerifyAndThen({ hre, name: 'Proxy__OVM_L1StandardBridge', contract: 'L1ChugSplashProxy', diff --git a/packages/contracts/deploy/010-AddressDictator.deploy.ts b/packages/contracts/deploy/010-AddressDictator.deploy.ts index 1aedcda3880b3..8092a16bd705b 100644 --- a/packages/contracts/deploy/010-AddressDictator.deploy.ts +++ b/packages/contracts/deploy/010-AddressDictator.deploy.ts @@ -4,7 +4,7 @@ import { hexStringEquals } from '@eth-optimism/core-utils' /* Imports: Internal */ import { - deployAndPostDeploy, + deployAndVerifyAndThen, getContractFromArtifact, } from '../src/hardhat-deploy-ethers' import { predeploys } from '../src/predeploys' @@ -74,7 +74,7 @@ const deployFn: DeployFunction = async (hre) => { return !hexStringEquals(existingAddresses[name], address) }) - await deployAndPostDeploy({ + await deployAndVerifyAndThen({ hre, name: 'AddressDictator', contract: 'AddressDictator', diff --git a/packages/contracts/deploy/011-set-addresses.ts b/packages/contracts/deploy/011-set-addresses.ts index 6f1321cb804ca..f78d9a1d1a1a1 100644 --- a/packages/contracts/deploy/011-set-addresses.ts +++ b/packages/contracts/deploy/011-set-addresses.ts @@ -1,10 +1,12 @@ /* Imports: External */ import { hexStringEquals, awaitCondition } from '@eth-optimism/core-utils' import { DeployFunction } from 'hardhat-deploy/dist/types' -import { defaultHardhatNetworkParams } from 'hardhat/internal/core/config/default-config' /* Imports: Internal */ -import { getContractFromArtifact } from '../src/hardhat-deploy-ethers' +import { + getContractFromArtifact, + isHardhatNode, +} from '../src/hardhat-deploy-ethers' const deployFn: DeployFunction = async (hre) => { const { deployer } = await hre.getNamedAccounts() @@ -72,11 +74,9 @@ const deployFn: DeployFunction = async (hre) => { (4) Wait for the deploy process to continue. `) - // Only execute this step if we're on the hardhat chain ID. This will only happen in CI. If this - // is the case, we can skip directly to transferring ownership over to the AddressDictator - // contract. - const { chainId } = await hre.ethers.provider.getNetwork() - if (chainId === defaultHardhatNetworkParams.chainId) { + // Check if if we're on the hardhat chain ID. This will only happen in CI. If this is the case, we + // can skip directly to transferring ownership over to the ChugSplashDictator contract. + if (await isHardhatNode(hre)) { const owner = await hre.ethers.getSigner(currentOwner) await Lib_AddressManager.connect(owner).transferOwnership( AddressDictator.address diff --git a/packages/contracts/deploy/013-ChugSplashDictator.deploy.ts b/packages/contracts/deploy/013-ChugSplashDictator.deploy.ts index eb88dc68624d9..b1afc18b1b7c0 100644 --- a/packages/contracts/deploy/013-ChugSplashDictator.deploy.ts +++ b/packages/contracts/deploy/013-ChugSplashDictator.deploy.ts @@ -7,7 +7,7 @@ import { predeploys } from '../src/predeploys' import { getContractDefinition } from '../src/contract-defs' import { getContractFromArtifact, - deployAndPostDeploy, + deployAndVerifyAndThen, } from '../src/hardhat-deploy-ethers' const deployFn: DeployFunction = async (hre) => { @@ -25,7 +25,7 @@ const deployFn: DeployFunction = async (hre) => { 'Proxy__OVM_L1CrossDomainMessenger' ) - await deployAndPostDeploy({ + await deployAndVerifyAndThen({ hre, name: 'ChugSplashDictator', contract: 'ChugSplashDictator', diff --git a/packages/contracts/deploy/014-OVM_L1StandardBridge.deploy.ts b/packages/contracts/deploy/014-OVM_L1StandardBridge.deploy.ts index 5173c4b94b924..19ff1088c2b6e 100644 --- a/packages/contracts/deploy/014-OVM_L1StandardBridge.deploy.ts +++ b/packages/contracts/deploy/014-OVM_L1StandardBridge.deploy.ts @@ -2,13 +2,13 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' import { ethers } from 'ethers' import { hexStringEquals, awaitCondition } from '@eth-optimism/core-utils' -import { defaultHardhatNetworkParams } from 'hardhat/internal/core/config/default-config' /* Imports: Internal */ import { getContractDefinition } from '../src/contract-defs' import { getContractFromArtifact, - deployAndPostDeploy, + deployAndVerifyAndThen, + isHardhatNode, } from '../src/hardhat-deploy-ethers' const deployFn: DeployFunction = async (hre) => { @@ -85,8 +85,7 @@ const deployFn: DeployFunction = async (hre) => { // Check if if we're on the hardhat chain ID. This will only happen in CI. If this is the case, we // can skip directly to transferring ownership over to the ChugSplashDictator contract. - const { chainId } = await hre.ethers.provider.getNetwork() - if (chainId === defaultHardhatNetworkParams.chainId) { + if (isHardhatNode(hre)) { const owner = await hre.ethers.getSigner(currentOwner) await Proxy__OVM_L1StandardBridge.connect(owner).setOwner( ChugSplashDictator.address @@ -131,7 +130,7 @@ const deployFn: DeployFunction = async (hre) => { // Deploy a copy of the implementation so it can be successfully verified on Etherscan. console.log(`Deploying a copy of the bridge for Etherscan verification...`) - await deployAndPostDeploy({ + await deployAndVerifyAndThen({ hre, name: 'L1StandardBridge_for_verification_only', contract: 'L1StandardBridge', diff --git a/packages/contracts/deploy/016-fund-accounts.ts b/packages/contracts/deploy/016-fund-accounts.ts index 7c89f9b002003..b4d8f15529949 100644 --- a/packages/contracts/deploy/016-fund-accounts.ts +++ b/packages/contracts/deploy/016-fund-accounts.ts @@ -1,22 +1,21 @@ /* 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 { defaultHardhatNetworkHdAccountsConfigParams } from 'hardhat/internal/core/config/default-config' import { normalizeHardhatNetworkAccountsConfig } from 'hardhat/internal/core/providers/util' /* Imports: Internal */ -import { getContractFromArtifact } from '../src/hardhat-deploy-ethers' +import { + getContractFromArtifact, + isHardhatNode, +} 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) { + if (await isHardhatNode(hre)) { const L1StandardBridge = await getContractFromArtifact( hre, 'Proxy__OVM_L1StandardBridge', diff --git a/packages/contracts/src/hardhat-deploy-ethers.ts b/packages/contracts/src/hardhat-deploy-ethers.ts index 82a1b00bac1de..fef6ab927e2b7 100644 --- a/packages/contracts/src/hardhat-deploy-ethers.ts +++ b/packages/contracts/src/hardhat-deploy-ethers.ts @@ -5,7 +5,7 @@ import { Signer } from '@ethersproject/abstract-signer' import { sleep, awaitCondition } from '@eth-optimism/core-utils' import { HttpNetworkConfig } from 'hardhat/types' -export const deployAndPostDeploy = async ({ +export const deployAndVerifyAndThen = async ({ hre, name, args, @@ -34,6 +34,22 @@ export const deployAndPostDeploy = async ({ await hre.ethers.provider.waitForTransaction(result.transactionHash) if (result.newlyDeployed) { + if (!isHardhatNode(hre)) { + // Verification sometimes fails, even when the contract is correctly deployed and eventually + // verified. Possibly due to a race condition. We don't want to halt the whole deployment + // process just because that happens. + try { + console.log('Verifying on Etherscan...') + await hre.run('verify:verify', { + address: result.address, + constructorArguments: args, + }) + console.log('Successfully verified') + } catch (error) { + console.log('Error when verifying bytecode on etherscan:') + console.log(error) + } + } if (postDeployAction) { const signer = hre.ethers.provider.getSigner(deployer) let abi = result.abi @@ -219,5 +235,10 @@ export const getContractFromArtifact = async ( }) } +export const isHardhatNode = async (hre) => { + const { chainId } = await hre.ethers.provider.getNetwork() + return chainId === 31337 +} + // Large balance to fund accounts with. export const BIG_BALANCE = ethers.BigNumber.from(`0xFFFFFFFFFFFFFFFFFFFF`)