Skip to content

Commit

Permalink
Contracts: connectL1Contracts & connectL2Contracts (#713)
Browse files Browse the repository at this point in the history
* Contracts: connect-contracts

* Trying to resolve build problems

* connect-contracts build working

* Adds artifacts-ovm back to gitignore

* Removes incorrect changes

* Adds copy-artifacts script

* Adds test file (not working yet)

* fix: incorrect contract instantiation

* Improves tests and removes old deployment versions

* Single source of truth for predeploy addresses

* Reverts deployments/README.md

* Makes connect-contracts more DRY

* Adds missing @ethersproject/abstract-signer dependency

* Adds argument evaluation

* Adds L1Contracts and L2Contracts types

* Attempts removing artifacts-ovm again

* Adds webpack config (not working yet)

* build: add artifacts to dist (#776)

* Updates lint rule

* Adds l2 imports

* Fixes dependency tree bug

* Removes webpack stuff

* Fixing package.json issues and adds .DS_Store to gitignore

* Removes test-contracts script

* Reverting script change

* Adds comments

* Adds comment

* Renames deployments folders

* Fixes linting errors

* Generates markdown

* build: add deployments directory to Dockerfiles

* Removes unneeded contracts, improves error handling and tests

* Adds changeset

* yarn.lock

* Removes console.log

* Changes from minor to patch version

* Fixes lint errors

Co-authored-by: Kelvin Fichter <[email protected]>
Co-authored-by: Liam Horne <[email protected]>
Co-authored-by: Georgios Konstantopoulos <[email protected]>
  • Loading branch information
4 people authored and tynes committed Jun 25, 2021
1 parent 3ed8788 commit 2419efb
Show file tree
Hide file tree
Showing 9 changed files with 376 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/fair-icons-argue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@eth-optimism/contracts': patch
---

"Adds connectL1Contracts and connectL2Contracts utility functions"
1 change: 1 addition & 0 deletions ops/docker/Dockerfile.batch-submitter
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ COPY --from=builder /optimism/packages/common-ts/package.json ./packages/common-
COPY --from=builder /optimism/packages/common-ts/dist ./packages/common-ts/dist

COPY --from=builder /optimism/packages/contracts/package.json ./packages/contracts/package.json
COPY --from=builder /optimism/packages/contracts/deployments ./packages/contracts/deployments
COPY --from=builder /optimism/packages/contracts/dist ./packages/contracts/dist
COPY --from=builder /optimism/packages/contracts/artifacts ./packages/contracts/artifacts
COPY --from=builder /optimism/packages/contracts/artifacts-ovm ./packages/contracts/artifacts-ovm
Expand Down
1 change: 1 addition & 0 deletions ops/docker/Dockerfile.data-transport-layer
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ COPY --from=builder /optimism/packages/common-ts/package.json ./packages/common-
COPY --from=builder /optimism/packages/common-ts/dist ./packages/common-ts/dist

COPY --from=builder /optimism/packages/contracts/package.json ./packages/contracts/package.json
COPY --from=builder /optimism/packages/contracts/deployments ./packages/contracts/deployments
COPY --from=builder /optimism/packages/contracts/dist ./packages/contracts/dist
COPY --from=builder /optimism/packages/contracts/artifacts ./packages/contracts/artifacts
COPY --from=builder /optimism/packages/contracts/artifacts-ovm ./packages/contracts/artifacts-ovm
Expand Down
1 change: 1 addition & 0 deletions ops/docker/Dockerfile.message-relayer
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ COPY --from=builder /optimism/packages/common-ts/package.json ./packages/common-
COPY --from=builder /optimism/packages/common-ts/dist ./packages/common-ts/dist

COPY --from=builder /optimism/packages/contracts/package.json ./packages/contracts/package.json
COPY --from=builder /optimism/packages/contracts/deployments ./packages/contracts/deployments
COPY --from=builder /optimism/packages/contracts/dist ./packages/contracts/dist
COPY --from=builder /optimism/packages/contracts/artifacts ./packages/contracts/artifacts
COPY --from=builder /optimism/packages/contracts/artifacts-ovm ./packages/contracts/artifacts-ovm
Expand Down
125 changes: 125 additions & 0 deletions packages/contracts/src/connect-contracts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { Signer, Contract, providers, ethers } from 'ethers'
import { Provider } from '@ethersproject/abstract-provider'
import { getL1ContractData, getL2ContractData } from './contract-data'

export type Network = 'goerli' | 'kovan' | 'mainnet'
interface L1Contracts {
addressManager: Contract
canonicalTransactionChain: Contract
executionManager: Contract
fraudVerifier: Contract
ethGateway: Contract
multiMessageRelayer: Contract
stateCommitmentChain: Contract
xDomainMessengerProxy: Contract
l1EthGatewayProxy: Contract
bondManager: Contract
}

interface L2Contracts {
eth: Contract
xDomainMessenger: Contract
messagePasser: Contract
messageSender: Contract
deployerWhiteList: Contract
ecdsaContractAccount: Contract
sequencerEntrypoint: Contract
erc1820Registry: Contract
addressManager: Contract
}

/**
* Validates user provided a singer or provider & throws error if not
*
* @param signerOrProvider
*/
const checkSignerType = (signerOrProvider: Signer | Provider) => {
if (!signerOrProvider) {
throw Error('signerOrProvider argument is undefined')
}
if (
!Provider.isProvider(signerOrProvider) &&
!Signer.isSigner(signerOrProvider)
) {
throw Error('signerOrProvider argument is the wrong type')
}
}

/**
* Connects a signer/provider to layer 1 contracts on a given network
*
* @param signerOrProvider ethers signer or provider
* @param network string denoting network
* @returns l1 contracts connected to signer/provider
*/
export const connectL1Contracts = async (
signerOrProvider: Signer | Provider,
network: Network
): Promise<L1Contracts> => {
checkSignerType(signerOrProvider)

if (!['mainnet', 'kovan', 'goerli'].includes(network)) {
throw Error('Must specify network: mainnet, kovan, or goerli.')
}

const l1ContractData = getL1ContractData(network)

const toEthersContract = (data) =>
new Contract(data.address, data.abi, signerOrProvider)

return {
addressManager: toEthersContract(l1ContractData.Lib_AddressManager),
canonicalTransactionChain: toEthersContract(
l1ContractData.OVM_CanonicalTransactionChain
),
executionManager: toEthersContract(l1ContractData.OVM_ExecutionManager),
fraudVerifier: toEthersContract(l1ContractData.OVM_FraudVerifier),
ethGateway: toEthersContract(l1ContractData.OVM_L1ETHGateway),
multiMessageRelayer: toEthersContract(
l1ContractData.OVM_L1MultiMessageRelayer
),
stateCommitmentChain: toEthersContract(
l1ContractData.OVM_StateCommitmentChain
),
xDomainMessengerProxy: toEthersContract(
l1ContractData.Proxy__OVM_L1CrossDomainMessenger
),
l1EthGatewayProxy: toEthersContract(l1ContractData.Proxy__OVM_L1ETHGateway),
// TODO: update this with actual bond manager when its ready
bondManager: toEthersContract(l1ContractData.mockOVM_BondManager),
}
}

/**
* Connects a signer/provider to layer 2 contracts (network agnostic)
*
* @param signerOrProvider ethers signer or provider
* @returns l2 contracts connected to signer/provider
*/
export const connectL2Contracts = async (
signerOrProvider
): Promise<L2Contracts> => {
const l2ContractData = await getL2ContractData()
checkSignerType(signerOrProvider)

const toEthersContract = (data) =>
new Contract(data.address, data.abi, signerOrProvider)

return {
eth: toEthersContract(l2ContractData.OVM_ETH),
xDomainMessenger: toEthersContract(
l2ContractData.OVM_L2CrossDomainMessenger
),
messagePasser: toEthersContract(l2ContractData.OVM_L2ToL1MessagePasser),
messageSender: toEthersContract(l2ContractData.OVM_L1MessageSender),
deployerWhiteList: toEthersContract(l2ContractData.OVM_DeployerWhitelist),
ecdsaContractAccount: toEthersContract(
l2ContractData.OVM_ECDSAContractAccount
),
sequencerEntrypoint: toEthersContract(
l2ContractData.OVM_SequencerEntrypoint
),
erc1820Registry: toEthersContract(l2ContractData.ERC1820Registry),
addressManager: toEthersContract(l2ContractData.Lib_AddressManager),
}
}
180 changes: 180 additions & 0 deletions packages/contracts/src/contract-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import { predeploys as l2Addresses } from './predeploys'
import { Network } from './connect-contracts'

/**
* This file is necessarily not DRY because it needs to be usable
* in a browser context and can't take advantage of dynamic imports
* (ie: the json needs to all be imported when transpiled)
*/

const Mainnet__Lib_AddressManager = require('../deployments/mainnet/Lib_AddressManager.json')
const Mainnet__OVM_CanonicalTransactionChain = require('../deployments/mainnet/OVM_CanonicalTransactionChain.json')
const Mainnet__OVM_ExecutionManager = require('../deployments/mainnet/OVM_ExecutionManager.json')
const Mainnet__OVM_FraudVerifier = require('../deployments/mainnet/OVM_FraudVerifier.json')
const Mainnet__OVM_L1CrossDomainMessenger = require('../deployments/mainnet/OVM_L1CrossDomainMessenger.json')
const Mainnet__OVM_L1ETHGateway = require('../deployments/mainnet/OVM_L1ETHGateway.json')
const Mainnet__OVM_L1MultiMessageRelayer = require('../deployments/mainnet/OVM_L1MultiMessageRelayer.json')
const Mainnet__OVM_SafetyChecker = require('../deployments/mainnet/OVM_SafetyChecker.json')
const Mainnet__OVM_StateCommitmentChain = require('../deployments/mainnet/OVM_StateCommitmentChain.json')
const Mainnet__OVM_StateManagerFactory = require('../deployments/mainnet/OVM_StateManagerFactory.json')
const Mainnet__OVM_StateTransitionerFactory = require('../deployments/mainnet/OVM_StateTransitionerFactory.json')
const Mainnet__Proxy__OVM_L1CrossDomainMessenger = require('../deployments/mainnet/Proxy__OVM_L1CrossDomainMessenger.json')
const Mainnet__Proxy__OVM_L1ETHGateway = require('../deployments/mainnet/Proxy__OVM_L1ETHGateway.json')
const Mainnet__mockOVM_BondManager = require('../deployments/mainnet/mockOVM_BondManager.json')

const Kovan__Lib_AddressManager = require('../deployments/kovan/Lib_AddressManager.json')
const Kovan__OVM_CanonicalTransactionChain = require('../deployments/kovan/OVM_CanonicalTransactionChain.json')
const Kovan__OVM_ExecutionManager = require('../deployments/kovan/OVM_ExecutionManager.json')
const Kovan__OVM_FraudVerifier = require('../deployments/kovan/OVM_FraudVerifier.json')
const Kovan__OVM_L1CrossDomainMessenger = require('../deployments/kovan/OVM_L1CrossDomainMessenger.json')
const Kovan__OVM_L1ETHGateway = require('../deployments/kovan/OVM_L1ETHGateway.json')
const Kovan__OVM_L1MultiMessageRelayer = require('../deployments/kovan/OVM_L1MultiMessageRelayer.json')
const Kovan__OVM_SafetyChecker = require('../deployments/kovan/OVM_SafetyChecker.json')
const Kovan__OVM_StateCommitmentChain = require('../deployments/kovan/OVM_StateCommitmentChain.json')
const Kovan__OVM_StateManagerFactory = require('../deployments/kovan/OVM_StateManagerFactory.json')
const Kovan__OVM_StateTransitionerFactory = require('../deployments/kovan/OVM_StateTransitionerFactory.json')
const Kovan__Proxy__OVM_L1CrossDomainMessenger = require('../deployments/kovan/Proxy__OVM_L1CrossDomainMessenger.json')
const Kovan__Proxy__OVM_L1ETHGateway = require('../deployments/kovan/Proxy__OVM_L1ETHGateway.json')
const Kovan__mockOVM_BondManager = require('../deployments/kovan/mockOVM_BondManager.json')

const Goerli__Lib_AddressManager = require('../deployments/goerli/Lib_AddressManager.json')
const Goerli__OVM_CanonicalTransactionChain = require('../deployments/goerli/OVM_CanonicalTransactionChain.json')
const Goerli__OVM_ExecutionManager = require('../deployments/goerli/OVM_ExecutionManager.json')
const Goerli__OVM_FraudVerifier = require('../deployments/goerli/OVM_FraudVerifier.json')
const Goerli__OVM_L1CrossDomainMessenger = require('../deployments/goerli/OVM_L1CrossDomainMessenger.json')
const Goerli__OVM_L1ETHGateway = require('../deployments/goerli/OVM_L1ETHGateway.json')
const Goerli__OVM_L1MultiMessageRelayer = require('../deployments/goerli/OVM_L1MultiMessageRelayer.json')
const Goerli__OVM_SafetyChecker = require('../deployments/goerli/OVM_SafetyChecker.json')
const Goerli__OVM_StateCommitmentChain = require('../deployments/goerli/OVM_StateCommitmentChain.json')
const Goerli__OVM_StateManagerFactory = require('../deployments/goerli/OVM_StateManagerFactory.json')
const Goerli__OVM_StateTransitionerFactory = require('../deployments/goerli/OVM_StateTransitionerFactory.json')
const Goerli__Proxy__OVM_L1CrossDomainMessenger = require('../deployments/goerli/Proxy__OVM_L1CrossDomainMessenger.json')
const Goerli__Proxy__OVM_L1ETHGateway = require('../deployments/goerli/Proxy__OVM_L1ETHGateway.json')
const Goerli__mockOVM_BondManager = require('../deployments/goerli/mockOVM_BondManager.json')

export const getL1ContractData = (network: Network) => {
return {
Lib_AddressManager: {
mainnet: Mainnet__Lib_AddressManager,
kovan: Kovan__Lib_AddressManager,
goerli: Goerli__Lib_AddressManager,
}[network],
OVM_CanonicalTransactionChain: {
mainnet: Mainnet__OVM_CanonicalTransactionChain,
kovan: Kovan__OVM_CanonicalTransactionChain,
goerli: Goerli__OVM_CanonicalTransactionChain,
}[network],
OVM_ExecutionManager: {
mainnet: Mainnet__OVM_ExecutionManager,
kovan: Kovan__OVM_ExecutionManager,
goerli: Goerli__OVM_ExecutionManager,
}[network],
OVM_FraudVerifier: {
mainnet: Mainnet__OVM_FraudVerifier,
kovan: Kovan__OVM_FraudVerifier,
goerli: Goerli__OVM_FraudVerifier,
}[network],
OVM_L1CrossDomainMessenger: {
mainnet: Mainnet__OVM_L1CrossDomainMessenger,
kovan: Kovan__OVM_L1CrossDomainMessenger,
goerli: Goerli__OVM_L1CrossDomainMessenger,
}[network],
OVM_L1ETHGateway: {
mainnet: Mainnet__OVM_L1ETHGateway,
kovan: Kovan__OVM_L1ETHGateway,
goerli: Goerli__OVM_L1ETHGateway,
}[network],
OVM_L1MultiMessageRelayer: {
mainnet: Mainnet__OVM_L1MultiMessageRelayer,
kovan: Kovan__OVM_L1MultiMessageRelayer,
goerli: Goerli__OVM_L1MultiMessageRelayer,
}[network],
OVM_SafetyChecker: {
mainnet: Mainnet__OVM_SafetyChecker,
kovan: Kovan__OVM_SafetyChecker,
goerli: Goerli__OVM_SafetyChecker,
}[network],
OVM_StateCommitmentChain: {
mainnet: Mainnet__OVM_StateCommitmentChain,
kovan: Kovan__OVM_StateCommitmentChain,
goerli: Goerli__OVM_StateCommitmentChain,
}[network],
OVM_StateManagerFactory: {
mainnet: Mainnet__OVM_StateManagerFactory,
kovan: Kovan__OVM_StateManagerFactory,
goerli: Goerli__OVM_StateManagerFactory,
}[network],
OVM_StateTransitionerFactory: {
mainnet: Mainnet__OVM_StateTransitionerFactory,
kovan: Kovan__OVM_StateTransitionerFactory,
goerli: Goerli__OVM_StateTransitionerFactory,
}[network],
Proxy__OVM_L1CrossDomainMessenger: {
mainnet: Mainnet__Proxy__OVM_L1CrossDomainMessenger,
kovan: Kovan__Proxy__OVM_L1CrossDomainMessenger,
goerli: Goerli__Proxy__OVM_L1CrossDomainMessenger,
}[network],
Proxy__OVM_L1ETHGateway: {
mainnet: Mainnet__Proxy__OVM_L1ETHGateway,
kovan: Kovan__Proxy__OVM_L1ETHGateway,
goerli: Goerli__Proxy__OVM_L1ETHGateway,
}[network],
mockOVM_BondManager: {
mainnet: Mainnet__mockOVM_BondManager,
kovan: Kovan__mockOVM_BondManager,
goerli: Goerli__mockOVM_BondManager,
}[network],
}
}

const OVM_ETH = require('../artifacts-ovm/contracts/optimistic-ethereum/OVM/predeploys/OVM_ETH.sol/OVM_ETH.json')
const OVM_L2CrossDomainMessenger = require('../artifacts-ovm/contracts/optimistic-ethereum/OVM/bridge/messaging/OVM_L2CrossDomainMessenger.sol/OVM_L2CrossDomainMessenger.json')
const OVM_L2ToL1MessagePasser = require('../artifacts-ovm/contracts/optimistic-ethereum/OVM/predeploys/OVM_L2ToL1MessagePasser.sol/OVM_L2ToL1MessagePasser.json')
const OVM_L1MessageSender = require('../artifacts-ovm/contracts/optimistic-ethereum/OVM/predeploys/OVM_L1MessageSender.sol/OVM_L1MessageSender.json')
const OVM_DeployerWhitelist = require('../artifacts-ovm/contracts/optimistic-ethereum/OVM/predeploys/OVM_DeployerWhitelist.sol/OVM_DeployerWhitelist.json')
const OVM_ECDSAContractAccount = require('../artifacts-ovm/contracts/optimistic-ethereum/OVM/accounts/OVM_ECDSAContractAccount.sol/OVM_ECDSAContractAccount.json')
const OVM_SequencerEntrypoint = require('../artifacts-ovm/contracts/optimistic-ethereum/OVM/predeploys/OVM_SequencerEntrypoint.sol/OVM_SequencerEntrypoint.json')
const ERC1820Registry = require('../artifacts-ovm/contracts/optimistic-ethereum/OVM/predeploys/ERC1820Registry.sol/ERC1820Registry.json')
const Lib_AddressManager = require('../artifacts-ovm/contracts/optimistic-ethereum/libraries/resolver/Lib_AddressManager.sol/Lib_AddressManager.json')

export const getL2ContractData = () => {
return {
OVM_ETH: {
abi: OVM_ETH.abi,
address: l2Addresses.OVM_ETH,
},
OVM_L2CrossDomainMessenger: {
abi: OVM_L2CrossDomainMessenger.abi,
address: l2Addresses.OVM_L2CrossDomainMessenger,
},
OVM_L2ToL1MessagePasser: {
abi: OVM_L2ToL1MessagePasser.abi,
address: l2Addresses.OVM_L2ToL1MessagePasser,
},
OVM_L1MessageSender: {
abi: OVM_L1MessageSender.abi,
address: l2Addresses.OVM_L1MessageSender,
},
OVM_DeployerWhitelist: {
abi: OVM_DeployerWhitelist.abi,
address: l2Addresses.OVM_DeployerWhitelist,
},
OVM_ECDSAContractAccount: {
abi: OVM_ECDSAContractAccount.abi,
address: l2Addresses.OVM_ECDSAContractAccount,
},
OVM_SequencerEntrypoint: {
abi: OVM_SequencerEntrypoint.abi,
address: l2Addresses.OVM_SequencerEntrypoint,
},
ERC1820Registry: {
abi: ERC1820Registry.abi,
address: l2Addresses.ERC1820Registry,
},
Lib_AddressManager: {
abi: Lib_AddressManager.abi,
address: l2Addresses.Lib_AddressManager,
},
}
}
1 change: 1 addition & 0 deletions packages/contracts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './contract-defs'
export * from './state-dump/get-dump'
export * from './contract-deployment'
export * from './predeploys'
export * from './connect-contracts'
Loading

0 comments on commit 2419efb

Please sign in to comment.