Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: deployment helper #140

Merged
merged 8 commits into from
Feb 15, 2024
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: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
"files": [
"src/",
"build/contracts/src",
"build/contracts/@openzeppelin"
"build/contracts/@openzeppelin",
"out/yul/Reader4844.yul/Reader4844.json"
],
"bugs": {
"url": "https://github.com/offchainlabs/nitro-contracts/issues"
},
"scripts": {
"prepublishOnly": "hardhat clean && hardhat compile",
"prepublishOnly": "hardhat clean && forge clean && hardhat compile && yarn build:forge:yul",
"build:all": "yarn build && yarn build:forge",
"build": "hardhat compile",
"build:forge:sol": "forge build --skip *.yul",
Expand Down
159 changes: 1 addition & 158 deletions scripts/deployment.ts
Original file line number Diff line number Diff line change
@@ -1,163 +1,6 @@
import { ethers } from 'hardhat'
import { ContractFactory, Contract } from 'ethers'
import '@nomiclabs/hardhat-ethers'
import { run } from 'hardhat'
import {
abi as UpgradeExecutorABI,
bytecode as UpgradeExecutorBytecode,
} from '@offchainlabs/upgrade-executor/build/contracts/src/UpgradeExecutor.sol/UpgradeExecutor.json'
import { maxDataSize } from './config'

// Define a verification function
async function verifyContract(
contractName: string,
contractAddress: string,
constructorArguments: any[] = [],
contractPathAndName?: string // optional
): Promise<void> {
try {
if (process.env.DISABLE_VERIFICATION) return
// Define the verification options with possible 'contract' property
const verificationOptions: {
contract?: string
address: string
constructorArguments: any[]
} = {
address: contractAddress,
constructorArguments: constructorArguments,
}

// if contractPathAndName is provided, add it to the verification options
if (contractPathAndName) {
verificationOptions.contract = contractPathAndName
}

await run('verify:verify', verificationOptions)
console.log(`Verified contract ${contractName} successfully.`)
} catch (error: any) {
if (error.message.includes('Already Verified')) {
console.log(`Contract ${contractName} is already verified.`)
} else {
console.error(
`Verification for ${contractName} failed with the following error: ${error.message}`
)
}
}
}

// Function to handle contract deployment
async function deployContract(
contractName: string,
signer: any,
constructorArgs: any[] = [],
verify: boolean = true
): Promise<Contract> {
const factory: ContractFactory = await ethers.getContractFactory(contractName)
const connectedFactory: ContractFactory = factory.connect(signer)
const contract: Contract = await connectedFactory.deploy(...constructorArgs)
await contract.deployTransaction.wait()
console.log(`New ${contractName} created at address:`, contract.address)

if (verify)
await verifyContract(contractName, contract.address, constructorArgs)

return contract
}

// Deploy upgrade executor from imported bytecode
async function deployUpgradeExecutor(): Promise<Contract> {
const upgradeExecutorFac = await ethers.getContractFactory(
UpgradeExecutorABI,
UpgradeExecutorBytecode
)
const upgradeExecutor = await upgradeExecutorFac.deploy()
return upgradeExecutor
}

// Function to handle all deployments of core contracts using deployContract function
async function deployAllContracts(
signer: any
): Promise<Record<string, Contract>> {
const ethBridge = await deployContract('Bridge', signer, [])
const ethSequencerInbox = await deployContract('SequencerInbox', signer, [
maxDataSize,
false,
])
const ethInbox = await deployContract('Inbox', signer, [maxDataSize])
const ethRollupEventInbox = await deployContract(
'RollupEventInbox',
signer,
[]
)
const ethOutbox = await deployContract('Outbox', signer, [])

const erc20Bridge = await deployContract('ERC20Bridge', signer, [])
const erc20SequencerInbox = await deployContract('SequencerInbox', signer, [
maxDataSize,
true,
])
const erc20Inbox = await deployContract('ERC20Inbox', signer, [maxDataSize])
const erc20RollupEventInbox = await deployContract(
'ERC20RollupEventInbox',
signer,
[]
)
const erc20Outbox = await deployContract('ERC20Outbox', signer, [])

const bridgeCreator = await deployContract('BridgeCreator', signer, [
[
ethBridge.address,
ethSequencerInbox.address,
ethInbox.address,
ethRollupEventInbox.address,
ethOutbox.address,
],
[
erc20Bridge.address,
erc20SequencerInbox.address,
erc20Inbox.address,
erc20RollupEventInbox.address,
erc20Outbox.address,
],
])
const prover0 = await deployContract('OneStepProver0', signer)
const proverMem = await deployContract('OneStepProverMemory', signer)
const proverMath = await deployContract('OneStepProverMath', signer)
const proverHostIo = await deployContract('OneStepProverHostIo', signer)
const osp: Contract = await deployContract('OneStepProofEntry', signer, [
prover0.address,
proverMem.address,
proverMath.address,
proverHostIo.address,
])
const challengeManager = await deployContract('ChallengeManager', signer)
const rollupAdmin = await deployContract('RollupAdminLogic', signer)
const rollupUser = await deployContract('RollupUserLogic', signer)
const upgradeExecutor = await deployUpgradeExecutor()
const validatorUtils = await deployContract('ValidatorUtils', signer)
const validatorWalletCreator = await deployContract(
'ValidatorWalletCreator',
signer
)
const rollupCreator = await deployContract('RollupCreator', signer)
const deployHelper = await deployContract('DeployHelper', signer)
return {
bridgeCreator,
prover0,
proverMem,
proverMath,
proverHostIo,
osp,
challengeManager,
rollupAdmin,
rollupUser,
upgradeExecutor,
validatorUtils,
validatorWalletCreator,
rollupCreator,
deployHelper,
}
}
import { deployAllContracts } from './deploymentUtils'

async function main() {
const [signer] = await ethers.getSigners()
Expand Down
191 changes: 191 additions & 0 deletions scripts/deploymentUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
import { ethers } from 'hardhat'
import { ContractFactory, Contract, Overrides } from 'ethers'
import '@nomiclabs/hardhat-ethers'
import { run } from 'hardhat'
import {
abi as UpgradeExecutorABI,
bytecode as UpgradeExecutorBytecode,
} from '@offchainlabs/upgrade-executor/build/contracts/src/UpgradeExecutor.sol/UpgradeExecutor.json'
import { maxDataSize } from './config'
import { Toolkit4844 } from '../test/contract/toolkit4844'
import { ArbSys__factory } from '../build/types'
import { ARB_SYS_ADDRESS } from '@arbitrum/sdk/dist/lib/dataEntities/constants'

// Define a verification function
export async function verifyContract(
contractName: string,
contractAddress: string,
constructorArguments: any[] = [],
contractPathAndName?: string // optional
): Promise<void> {
try {
if (process.env.DISABLE_VERIFICATION) return
// Define the verification options with possible 'contract' property
const verificationOptions: {
contract?: string
address: string
constructorArguments: any[]
} = {
address: contractAddress,
constructorArguments: constructorArguments,
}

// if contractPathAndName is provided, add it to the verification options
if (contractPathAndName) {
verificationOptions.contract = contractPathAndName
}

await run('verify:verify', verificationOptions)
console.log(`Verified contract ${contractName} successfully.`)
} catch (error: any) {
if (error.message.includes('Already Verified')) {
console.log(`Contract ${contractName} is already verified.`)
} else {
console.error(
`Verification for ${contractName} failed with the following error: ${error.message}`
)
}
}
}

// Function to handle contract deployment
export async function deployContract(
contractName: string,
signer: any,
constructorArgs: any[] = [],
verify: boolean = true,
overrides?: Overrides
): Promise<Contract> {
const factory: ContractFactory = await ethers.getContractFactory(contractName)
const connectedFactory: ContractFactory = factory.connect(signer)

let deploymentArgs = [...constructorArgs]
if (overrides) {
deploymentArgs.push(overrides)
}

const contract: Contract = await connectedFactory.deploy(...deploymentArgs)
await contract.deployTransaction.wait()
console.log(`New ${contractName} created at address:`, contract.address)

if (verify)
await verifyContract(contractName, contract.address, constructorArgs)

return contract
}

// Deploy upgrade executor from imported bytecode
export async function deployUpgradeExecutor(signer: any): Promise<Contract> {
const upgradeExecutorFac = await ethers.getContractFactory(
UpgradeExecutorABI,
UpgradeExecutorBytecode
)
const connectedFactory: ContractFactory = upgradeExecutorFac.connect(signer)
const upgradeExecutor = await connectedFactory.deploy()
return upgradeExecutor
}

// Function to handle all deployments of core contracts using deployContract function
export async function deployAllContracts(
signer: any
): Promise<Record<string, Contract>> {
const isOnArb = await _isRunningOnArbitrum(signer)

const ethBridge = await deployContract('Bridge', signer, [])
const reader4844 = isOnArb
? ethers.constants.AddressZero
: (await Toolkit4844.deployReader4844(signer)).address

const ethSequencerInbox = await deployContract('SequencerInbox', signer, [
maxDataSize,
reader4844,
false,
])

const ethInbox = await deployContract('Inbox', signer, [maxDataSize])
const ethRollupEventInbox = await deployContract(
'RollupEventInbox',
signer,
[]
)
const ethOutbox = await deployContract('Outbox', signer, [])

const erc20Bridge = await deployContract('ERC20Bridge', signer, [])
const erc20SequencerInbox = await deployContract('SequencerInbox', signer, [
maxDataSize,
reader4844,
true,
])
const erc20Inbox = await deployContract('ERC20Inbox', signer, [maxDataSize])
const erc20RollupEventInbox = await deployContract(
'ERC20RollupEventInbox',
signer,
[]
)
const erc20Outbox = await deployContract('ERC20Outbox', signer, [])

const bridgeCreator = await deployContract('BridgeCreator', signer, [
[
ethBridge.address,
ethSequencerInbox.address,
ethInbox.address,
ethRollupEventInbox.address,
ethOutbox.address,
],
[
erc20Bridge.address,
erc20SequencerInbox.address,
erc20Inbox.address,
erc20RollupEventInbox.address,
erc20Outbox.address,
],
])
const prover0 = await deployContract('OneStepProver0', signer)
const proverMem = await deployContract('OneStepProverMemory', signer)
const proverMath = await deployContract('OneStepProverMath', signer)
const proverHostIo = await deployContract('OneStepProverHostIo', signer)
const osp: Contract = await deployContract('OneStepProofEntry', signer, [
prover0.address,
proverMem.address,
proverMath.address,
proverHostIo.address,
])
const challengeManager = await deployContract('ChallengeManager', signer)
const rollupAdmin = await deployContract('RollupAdminLogic', signer)
const rollupUser = await deployContract('RollupUserLogic', signer)
const upgradeExecutor = await deployUpgradeExecutor(signer)
const validatorUtils = await deployContract('ValidatorUtils', signer)
const validatorWalletCreator = await deployContract(
'ValidatorWalletCreator',
signer
)
const rollupCreator = await deployContract('RollupCreator', signer)
const deployHelper = await deployContract('DeployHelper', signer)
return {
bridgeCreator,
prover0,
proverMem,
proverMath,
proverHostIo,
osp,
challengeManager,
rollupAdmin,
rollupUser,
upgradeExecutor,
validatorUtils,
validatorWalletCreator,
rollupCreator,
deployHelper,
}
}

// Check if we're deploying to an Arbitrum chain
async function _isRunningOnArbitrum(signer: any): Promise<Boolean> {
const arbSys = ArbSys__factory.connect(ARB_SYS_ADDRESS, signer)
try {
await arbSys.arbOSVersion()
return true
} catch (error) {
return false
}
}
Loading
Loading