Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/clean-buttons-think.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@eth-optimism/contracts': patch
---

Run etherscan verification after each contract is deployed.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'

/* Imports: Internal */
import {
deployAndPostDeploy,
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'

Expand All @@ -13,7 +13,7 @@ const deployFn: DeployFunction = async (hre) => {
'Lib_AddressManager'
)

await deployAndPostDeploy({
await deployAndVerifyAndThen({
hre,
name: 'ChainStorageContainer-CTC-batches',
contract: 'ChainStorageContainer',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'

/* Imports: Internal */
import {
deployAndPostDeploy,
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'

Expand All @@ -13,7 +13,7 @@ const deployFn: DeployFunction = async (hre) => {
'Lib_AddressManager'
)

await deployAndPostDeploy({
await deployAndVerifyAndThen({
hre,
name: 'ChainStorageContainer-SCC-batches',
contract: 'ChainStorageContainer',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'

/* Imports: Internal */
import {
deployAndPostDeploy,
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'

Expand All @@ -13,7 +13,7 @@ const deployFn: DeployFunction = async (hre) => {
'Lib_AddressManager'
)

await deployAndPostDeploy({
await deployAndVerifyAndThen({
hre,
name: 'CanonicalTransactionChain',
args: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'

/* Imports: Internal */
import {
deployAndPostDeploy,
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'

Expand All @@ -13,7 +13,7 @@ const deployFn: DeployFunction = async (hre) => {
'Lib_AddressManager'
)

await deployAndPostDeploy({
await deployAndVerifyAndThen({
hre,
name: 'StateCommitmentChain',
args: [
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts/deploy/006-OVM_BondManager.deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'

/* Imports: Internal */
import {
deployAndPostDeploy,
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'

Expand All @@ -13,7 +13,7 @@ const deployFn: DeployFunction = async (hre) => {
'Lib_AddressManager'
)

await deployAndPostDeploy({
await deployAndVerifyAndThen({
hre,
name: 'BondManager',
args: [Lib_AddressManager.address],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { hexStringEquals, awaitCondition } from '@eth-optimism/core-utils'

/* Imports: Internal */
import {
deployAndPostDeploy,
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'

Expand All @@ -14,7 +14,7 @@ const deployFn: DeployFunction = async (hre) => {
'Lib_AddressManager'
)

await deployAndPostDeploy({
await deployAndVerifyAndThen({
hre,
name: 'OVM_L1CrossDomainMessenger',
contract: 'L1CrossDomainMessenger',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'

/* Imports: Internal */
import {
deployAndPostDeploy,
deployAndVerifyAndThen,
getContractFromArtifact,
} from '../src/hardhat-deploy-ethers'

Expand All @@ -13,7 +13,7 @@ const deployFn: DeployFunction = async (hre) => {
'Lib_AddressManager'
)

await deployAndPostDeploy({
await deployAndVerifyAndThen({
hre,
name: 'Proxy__OVM_L1CrossDomainMessenger',
contract: 'Lib_ResolvedDelegateProxy',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts/deploy/010-AddressDictator.deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -74,7 +74,7 @@ const deployFn: DeployFunction = async (hre) => {
return !hexStringEquals(existingAddresses[name], address)
})

await deployAndPostDeploy({
await deployAndVerifyAndThen({
hre,
name: 'AddressDictator',
contract: 'AddressDictator',
Expand Down
14 changes: 7 additions & 7 deletions packages/contracts/deploy/011-set-addresses.ts
Original file line number Diff line number Diff line change
@@ -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()
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts/deploy/013-ChugSplashDictator.deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -25,7 +25,7 @@ const deployFn: DeployFunction = async (hre) => {
'Proxy__OVM_L1CrossDomainMessenger'
)

await deployAndPostDeploy({
await deployAndVerifyAndThen({
hre,
name: 'ChugSplashDictator',
contract: 'ChugSplashDictator',
Expand Down
9 changes: 4 additions & 5 deletions packages/contracts/deploy/014-OVM_L1StandardBridge.deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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',
Expand Down
13 changes: 6 additions & 7 deletions packages/contracts/deploy/016-fund-accounts.ts
Original file line number Diff line number Diff line change
@@ -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',
Expand Down
23 changes: 22 additions & 1 deletion packages/contracts/src/hardhat-deploy-ethers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the error?

Copy link
Contributor Author

@maurelian maurelian Nov 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually this, which happens on Kovan because the identical source code has already been verified.

NomicLabsHardhatPluginError: The Etherscan API responded with a failure status.
The verification may still succeed but should be checked manually.
Reason: Already Verified

I could detect that particular error and throw on everything else, but IMO halting the deployment based on an external failure from the Etherscan API would be an overreaction. Catching any errors on this call seems like the best approach, as we can always go back and manually verify a single contract quite easily vs. restarting the process mid-deployment which feels more distuptive to me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's fine. I'll just request that we open up an issue on GH to make this more robust in the future.

// 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
Expand Down Expand Up @@ -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`)