Skip to content
This repository was archived by the owner on Apr 12, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
4d014f0
Another stab at a good hardhat-deploy
smartcontracts Feb 24, 2021
b3e75a8
Testing etherscan verifications
smartcontracts Feb 25, 2021
35514e2
Fix linting
smartcontracts Feb 25, 2021
405ff56
Merge branch 'master' into feat/hardhat-deploy-v2
smartcontracts Feb 25, 2021
1c19f10
merging master
smartcontracts Mar 25, 2021
86826e1
remove artifacts
smartcontracts Mar 25, 2021
abef762
keep old deploy script
smartcontracts Mar 25, 2021
f717b5a
remove old hardhat-typechain dependency
smartcontracts Mar 25, 2021
4be40ab
remove unused import
smartcontracts Mar 25, 2021
0b320e0
remove kovan config
smartcontracts Mar 26, 2021
024966b
Tweak deployment a bit
smartcontracts Mar 26, 2021
e0acec7
Clean up defaults
smartcontracts Mar 26, 2021
9cc3ad3
rename hardhat => hh
smartcontracts Mar 26, 2021
1f2c7e5
Use mock bond manager
smartcontracts Mar 26, 2021
cf9dcc1
Make deploy a bit more robust
smartcontracts Mar 26, 2021
2e9f3d0
I committed my private key again. There goes my goerli eth
smartcontracts Mar 26, 2021
46af00f
and my infura api key too
smartcontracts Mar 26, 2021
c978988
Fix lint errors
smartcontracts Mar 26, 2021
aba6d1f
Use strict ordering
smartcontracts Mar 26, 2021
a5c62ff
Merge branch 'master' into feat/hardhat-deploy-v2
smartcontracts Mar 26, 2021
34de74c
Merge branch 'master' into feat/hardhat-deploy-v2
smartcontracts Mar 26, 2021
219c9c1
refactor: use helper for easy AddressManager deployments (#350)
gakonst Mar 27, 2021
7422488
Clean up georgios pr
smartcontracts Mar 27, 2021
f451546
tweak deploy to only include primary contracts
smartcontracts Apr 7, 2021
86b2f4d
use dotenv to manage deployer keys
smartcontracts Apr 7, 2021
f3b2b7e
Update src/hardhat-deploy-ethers.ts
smartcontracts Apr 7, 2021
b99dd5b
Stricter checking on address set
smartcontracts Apr 7, 2021
b60c6b5
add argument for sequencer address
smartcontracts Apr 7, 2021
b5e02af
minor tweaks to console.log comments
smartcontracts Apr 7, 2021
1c685a4
move predeploy addresses into their own file
smartcontracts Apr 7, 2021
186490c
add small comment for clarity
smartcontracts Apr 7, 2021
fce852a
update deploy script
smartcontracts Apr 8, 2021
9bf7288
fix incorrect env var in deploy script
smartcontracts Apr 8, 2021
a3e9447
adding deploy.js shim to get ci to work
smartcontracts Apr 8, 2021
8e79dc2
simplify deployment environment vars
smartcontracts Apr 8, 2021
7046b54
temporary tweaks to get a ci run to pass
smartcontracts Apr 8, 2021
35c6888
merge master
smartcontracts Apr 8, 2021
2544668
print out deploy artifacts
smartcontracts Apr 8, 2021
59260bf
fix artifact log output format
smartcontracts Apr 8, 2021
d08136c
fix contract names in artifact log output
smartcontracts Apr 8, 2021
3430623
add eth gateway to deploy
smartcontracts Apr 8, 2021
0be6832
add OVM_Proposer to address manager
smartcontracts Apr 8, 2021
1a280c5
add some comments for clarity
smartcontracts Apr 8, 2021
1cfe7ee
remove bytecode hash from compiler settings
smartcontracts Apr 8, 2021
77d0e88
minor tweaks in response to review
smartcontracts Apr 8, 2021
60e5d39
Merge branch 'master' into feat/hardhat-deploy-v2
smartcontracts Apr 8, 2021
c45e3d6
transfer address manager ownership after deploy
smartcontracts Apr 8, 2021
6eb021e
Merge branch 'feat/hardhat-deploy-v2' of github.com:ethereum-optimism…
smartcontracts Apr 8, 2021
bc79723
explicitly attach deployer to address manager
smartcontracts Apr 8, 2021
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
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# name of the network to deploy to e.g., kovan or mainnet
CONTRACTS_TARGET_NETWORK=
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can we comment these for extra completion points? :D


# private key for the account that will execute the deploy
CONTRACTS_DEPLOYER_KEY=

# rpc url for the node that will receive deploy transactions
CONTRACTS_RPC_URL=
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ build/
# Coverage output
coverage/
coverage.json

# Environment variables
.env
159 changes: 43 additions & 116 deletions bin/deploy.js
Original file line number Diff line number Diff line change
@@ -1,120 +1,47 @@
#!/usr/bin/env node

const contracts = require('../build/src/contract-deployment/deploy');
const { providers, Wallet, utils, ethers } = require('ethers');
const { LedgerSigner } = require('@ethersproject/hardware-wallets');
const { JsonRpcProvider } = providers;

const env = process.env;
const key = env.DEPLOYER_PRIVATE_KEY;
const sequencerKey = env.SEQUENCER_PRIVATE_KEY;
let SEQUENCER_ADDRESS = env.SEQUENCER_ADDRESS;
const web3Url = env.L1_NODE_WEB3_URL || 'http://127.0.0.1:8545';
const DEPLOY_TX_GAS_LIMIT = env.DEPLOY_TX_GAS_LIMIT || 5000000;
const MIN_TRANSACTION_GAS_LIMIT = env.MIN_TRANSACTION_GAS_LIMIT || 50000;
const MAX_TRANSACTION_GAS_LIMIT = env.MAX_TRANSACTION_GAS_LIMIT || 9000000;
const MAX_GAS_PER_QUEUE_PER_EPOCH = env.MAX_GAS_PER_QUEUE_PER_EPOCH || 250000000;
const SECONDS_PER_EPOCH = env.SECONDS_PER_EPOCH || 0;
const WAIT_FOR_RECEIPTS = env.WAIT_FOR_RECEIPTS === 'true';
let WHITELIST_OWNER = env.WHITELIST_OWNER;
const WHITELIST_ALLOW_ARBITRARY_CONTRACT_DEPLOYMENT = env.WHITELIST_ALLOW_ARBITRARY_CONTRACT_DEPLOYMENT || true;
const FORCE_INCLUSION_PERIOD_SECONDS = env.FORCE_INCLUSION_PERIOD_SECONDS || 2592000; // 30 days
const FRAUD_PROOF_WINDOW_SECONDS = env.FRAUD_PROOF_WINDOW_SECONDS || (60 * 60 * 24 * 7); // 7 days
const SEQUENCER_PUBLISH_WINDOW_SECONDS = env.SEQUENCER_PUBLISH_WINDOW_SECONDS || (60 * 30); // 30 min
const CHAIN_ID = env.CHAIN_ID || 420; // layer 2 chainid
const USE_LEDGER = env.USE_LEDGER || false;
const ADDRESS_MANAGER_ADDRESS = env.ADDRESS_MANAGER_ADDRESS || undefined;
const HD_PATH = env.HD_PATH || utils.defaultPath;
const BLOCK_TIME_SECONDS = env.BLOCK_TIME_SECONDS || 15;
const L2_CROSS_DOMAIN_MESSENGER_ADDRESS =
env.L2_CROSS_DOMAIN_MESSENGER_ADDRESS || '0x4200000000000000000000000000000000000007';
let RELAYER_ADDRESS = env.RELAYER_ADDRESS || '0x0000000000000000000000000000000000000000';
const RELAYER_PRIVATE_KEY = env.RELAYER_PRIVATE_KEY;

(async () => {
const provider = new JsonRpcProvider(web3Url);
let signer;

// Use the ledger for the deployer
if (USE_LEDGER) {
signer = new LedgerSigner(provider, 'default', HD_PATH);
} else {
if (typeof key === 'undefined')
throw new Error('Must pass deployer key as DEPLOYER_PRIVATE_KEY');
signer = new Wallet(key, provider);
const path = require('path')
const { spawn } = require('child_process')
const dirtree = require('directory-tree')

const main = async () => {
const task = spawn(path.join(__dirname, 'deploy.ts'))

await new Promise((resolve) => {
task.on('exit', () => {
resolve()
})
})

// Stuff below this line is currently required for CI to work properly. We probably want to
// update our CI so this is no longer necessary. But I'm adding it for backwards compat so we can
// get the hardhat-deploy stuff merged. Woot.
const nicknames = {
'Lib_AddressManager': 'AddressManager',
'mockOVM_BondManager': 'OVM_BondManager'
}

if (SEQUENCER_ADDRESS) {
if (!utils.isAddress(SEQUENCER_ADDRESS))
throw new Error(`Invalid Sequencer Address: ${SEQUENCER_ADDRESS}`);
} else {
if (!sequencerKey)
throw new Error('Must pass sequencer key as SEQUENCER_PRIVATE_KEY');
const sequencer = new Wallet(sequencerKey, provider);
SEQUENCER_ADDRESS = await sequencer.getAddress();
}

if (typeof WHITELIST_OWNER === 'undefined')
WHITELIST_OWNER = signer;

// Use the address derived from RELAYER_PRIVATE_KEY if a private key
// is passed. Using the zero address as the relayer address will mean
// there is no relayer authentication.
if (RELAYER_PRIVATE_KEY) {
if (!utils.isAddress(RELAYER_ADDRESS))
throw new Error(`Invalid Relayer Address: ${RELAYER_ADDRESS}`);
const relayer = new Wallet(RELAYER_PRIVATE_KEY, provider);
RELAYER_ADDRESS = await relayer.getAddress();
}

const result = await contracts.deploy({
deploymentSigner: signer,
transactionChainConfig: {
forceInclusionPeriodSeconds: FORCE_INCLUSION_PERIOD_SECONDS,
sequencer: SEQUENCER_ADDRESS,
forceInclusionPeriodBlocks: Math.ceil(FORCE_INCLUSION_PERIOD_SECONDS/BLOCK_TIME_SECONDS),
},
stateChainConfig: {
fraudProofWindowSeconds: FRAUD_PROOF_WINDOW_SECONDS,
sequencerPublishWindowSeconds: SEQUENCER_PUBLISH_WINDOW_SECONDS,
},
ovmGlobalContext: {
ovmCHAINID: CHAIN_ID,
L2CrossDomainMessengerAddress: L2_CROSS_DOMAIN_MESSENGER_ADDRESS
},
l1CrossDomainMessengerConfig: {
relayerAddress: RELAYER_ADDRESS,
},
ovmGasMeteringConfig: {
minTransactionGasLimit: MIN_TRANSACTION_GAS_LIMIT,
maxTransactionGasLimit: MAX_TRANSACTION_GAS_LIMIT,
maxGasPerQueuePerEpoch: MAX_GAS_PER_QUEUE_PER_EPOCH,
secondsPerEpoch: SECONDS_PER_EPOCH
},
whitelistConfig: {
owner: WHITELIST_OWNER,
allowArbitraryContractDeployment: WHITELIST_ALLOW_ARBITRARY_CONTRACT_DEPLOYMENT
},
deployOverrides: {
gasLimit: DEPLOY_TX_GAS_LIMIT
},
waitForReceipts: WAIT_FOR_RECEIPTS,
addressManager: ADDRESS_MANAGER_ADDRESS,
});

const { failedDeployments, AddressManager } = result;
if (failedDeployments.length !== 0)
throw new Error(`Contract deployment failed: ${failedDeployments.join(',')}`);

const out = {};
out.AddressManager = AddressManager.address;
out.OVM_Sequencer = SEQUENCER_ADDRESS;
out.Deployer = await signer.getAddress()
for (const [name, contract] of Object.entries(result.contracts)) {
out[name] = contract.address;
}
console.log(JSON.stringify(out, null, 2));
})().catch(err => {
console.log(JSON.stringify({error: err.message, stack: err.stack}, null, 2));
process.exit(1);
});
const contracts = dirtree(
path.resolve(__dirname, `../deployments/custom`)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this "custom" really means "CI" right now

).children.filter((child) => {
return child.extension === '.json'
}).reduce((contracts, child) => {
const contractName = child.name.replace('.json', '')
const artifact = require(path.resolve(__dirname, `../deployments/custom/${child.name}`))
contracts[nicknames[contractName] || contractName] = artifact.address
return contracts
}, {})

// We *must* console.log here because CI will pipe the output of this script into an
// addresses.json file. Also something we should probably remove.
console.log(JSON.stringify(contracts, null, 2))
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.log(
JSON.stringify({ error: error.message, stack: error.stack }, null, 2)
)
process.exit(1)
})
46 changes: 46 additions & 0 deletions bin/deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env ts-node-script

import { Wallet } from 'ethers'

// Ensures that all relevant environment vars are properly set. These lines *must* come before the
// hardhat import because importing will load the config (which relies on these vars). Necessary
// because CI currently uses different var names than the ones we've chosen here.
// TODO: Update CI so that we don't have to do this anymore.
process.env.HARDHAT_NETWORK = 'custom' // "custom" here is an arbitrary name. only used for CI.
process.env.CONTRACTS_TARGET_NETWORK = 'custom'
process.env.CONTRACTS_DEPLOYER_KEY = process.env.DEPLOYER_PRIVATE_KEY
process.env.CONTRACTS_RPC_URL =
process.env.L1_NODE_WEB3_URL || 'http://127.0.0.1:8545'

import hre from 'hardhat'

const main = async () => {
const sequencer = new Wallet(process.env.SEQUENCER_PRIVATE_KEY)
const deployer = new Wallet(process.env.DEPLOYER_PRIVATE_KEY)

await hre.run('deploy', {
l1BlockTimeSeconds: process.env.BLOCK_TIME_SECONDS,
ctcForceInclusionPeriodSeconds: process.env.FORCE_INCLUSION_PERIOD_SECONDS,
ctcMaxTransactionGasLimit: process.env.MAX_TRANSACTION_GAS_LIMIT,
emMinTransactionGasLimit: process.env.MIN_TRANSACTION_GAS_LIMIT,
emMaxtransactionGasLimit: process.env.MAX_TRANSACTION_GAS_LIMIT,
emMaxGasPerQueuePerEpoch: process.env.MAX_GAS_PER_QUEUE_PER_EPOCH,
emSecondsPerEpoch: process.env.SECONDS_PER_EPOCH,
emOvmChainId: process.env.CHAIN_ID,
sccFraudProofWindow: parseInt(process.env.FRAUD_PROOF_WINDOW_SECONDS, 10),
sccSequencerPublishWindow: process.env.SEQUENCER_PUBLISH_WINDOW_SECONDS,
ovmSequencerAddress: sequencer.address,
ovmProposerAddress: sequencer.address,
ovmRelayerAddress: sequencer.address,
ovmAddressManagerOwner: deployer.address,
})
}

Copy link
Copy Markdown
Collaborator

@tynes tynes Apr 8, 2021

Choose a reason for hiding this comment

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

Small nit as then needs to be deprecated

;(async () => {
   const addresses = await main()
   console.log(JSON.stringify(addresses, null, 2))
})().catch(err => {

})

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Was following https://hardhat.org/guides/scripts.html. And the ;(...)() syntax was giving me a lot of headache with the linter so I went with this.

main()
.then(() => process.exit(0))
.catch((error) => {
console.log(
JSON.stringify({ error: error.message, stack: error.stack }, null, 2)
)
process.exit(1)
})
51 changes: 51 additions & 0 deletions deploy/000-Lib_AddressManager.deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'

/* Imports: Internal */
import { registerAddress } from '../src/hardhat-deploy-ethers'
import { predeploys } from '../src/predeploys'

const deployFn: DeployFunction = async (hre) => {
const { deploy } = hre.deployments
const { deployer } = await hre.getNamedAccounts()

await deploy('Lib_AddressManager', {
from: deployer,
args: [],
log: true,
})

await registerAddress({
hre,
name: 'OVM_L2CrossDomainMessenger',
address: predeploys.OVM_L2CrossDomainMessenger,
})

await registerAddress({
hre,
name: 'OVM_DecompressionPrecompileAddress',
address: predeploys.OVM_SequencerEntrypoint,
})

await registerAddress({
hre,
name: 'OVM_Sequencer',
address: (hre as any).deployConfig.ovmSequencerAddress,
})

await registerAddress({
hre,
name: 'OVM_Proposer',
address: (hre as any).deployConfig.ovmProposerAddress,
})

await registerAddress({
hre,
name: 'OVM_L2BatchMessageRelayer',
address: (hre as any).deployConfig.ovmRelayerAddress,
})
}

deployFn.tags = ['Lib_AddressManager', 'required']

export default deployFn
27 changes: 27 additions & 0 deletions deploy/001-OVM_ChainStorageContainer_ctc_batches.deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'

/* Imports: Internal */
import {
deployAndRegister,
getDeployedContract,
} from '../src/hardhat-deploy-ethers'

const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager'
)

await deployAndRegister({
hre,
name: 'OVM_ChainStorageContainer:CTC:batches',
contract: 'OVM_ChainStorageContainer',
args: [Lib_AddressManager.address, 'OVM_CanonicalTransactionChain'],
})
}

deployFn.dependencies = ['Lib_AddressManager']
deployFn.tags = ['OVM_ChainStorageContainer_ctc_batches']

export default deployFn
27 changes: 27 additions & 0 deletions deploy/002-OVM_ChainStorageContainer_ctc_queue.deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'

/* Imports: Internal */
import {
deployAndRegister,
getDeployedContract,
} from '../src/hardhat-deploy-ethers'

const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager'
)

await deployAndRegister({
hre,
name: 'OVM_ChainStorageContainer:CTC:queue',
contract: 'OVM_ChainStorageContainer',
args: [Lib_AddressManager.address, 'OVM_CanonicalTransactionChain'],
})
}

deployFn.dependencies = ['Lib_AddressManager']
deployFn.tags = ['OVM_ChainStorageContainer_ctc_queue']

export default deployFn
27 changes: 27 additions & 0 deletions deploy/003-OVM_ChainStorageContainer_scc_batches.deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'

/* Imports: Internal */
import {
deployAndRegister,
getDeployedContract,
} from '../src/hardhat-deploy-ethers'

const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager'
)

await deployAndRegister({
hre,
name: 'OVM_ChainStorageContainer:SCC:batches',
contract: 'OVM_ChainStorageContainer',
args: [Lib_AddressManager.address, 'OVM_StateCommitmentChain'],
})
}

deployFn.dependencies = ['Lib_AddressManager']
deployFn.tags = ['OVM_ChainStorageContainer_scc_batches']

export default deployFn
31 changes: 31 additions & 0 deletions deploy/004-OVM_CanonicalTransactionChain.deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'

/* Imports: Internal */
import {
deployAndRegister,
getDeployedContract,
} from '../src/hardhat-deploy-ethers'

const deployFn: DeployFunction = async (hre) => {
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager'
)

await deployAndRegister({
hre,
name: 'OVM_CanonicalTransactionChain',
args: [
Lib_AddressManager.address,
(hre as any).deployConfig.ctcForceInclusionPeriodSeconds,
(hre as any).deployConfig.ctcForceInclusionPeriodBlocks,
(hre as any).deployConfig.ctcMaxTransactionGasLimit,
],
})
}

deployFn.dependencies = ['Lib_AddressManager']
deployFn.tags = ['OVM_CanonicalTransactionChain']

export default deployFn
Loading