Commit e4fbde24 authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge pull request #2430 from ethereum-optimism/develop

Develop -> Master PR
parents 71240b1d 1d2567cd
---
'@eth-optimism/go-builder': patch
'@eth-optimism/js-builder': patch
---
Trigger releases
---
'@eth-optimism/sdk': minor
---
New isL2Provider helper function. Internal cleanups.
---
'@eth-optimism/contracts': patch
---
Remove l2 gas price hardhat task
......@@ -37,4 +37,6 @@ M-ops:
- any: ['ops/**/*']
C-Protocol-Critical:
- any: ['packages/data-transport-layer/**/*.ts', 'packages/contracts/**/*.sol', 'l2geth/**/*.go']
- 'packages/data-transport-layer/**/*.ts'
- 'packages/contracts/**/*.sol'
- 'l2geth/**/*.go'
---
name: 'Changeset integrity checker'
on:
- pull_request_target
jobs:
changesets-integrity-checker:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: 'changeset status'
run: npx changeset status
......@@ -12,6 +12,6 @@ jobs:
stale-pr-message: 'This PR is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
exempt-pr-labels: exempt-stale
days-before-issue-stale: 999
dats-before-pr-stale: 14
days-before-pr-stale: 14
days-before-close: 5
repo-token: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
......@@ -152,7 +152,7 @@ jobs:
go-builder:
name: Publish go-builder ${{ needs.release.outputs.go-builder }}
needs: release
if: needs.release.go-builder != ''
if: needs.release.outputs.go-builder != ''
runs-on: ubuntu-latest
steps:
- name: Checkout
......@@ -178,7 +178,7 @@ jobs:
js-builder:
name: Publish js-builder ${{ needs.release.outputs.js-builder }}
needs: release
if: needs.release.js-builder != ''
if: needs.release.outputs.js-builder != ''
runs-on: ubuntu-latest
steps:
- name: Checkout
......
#!/bin/sh
set -e
RPC_URL=${RPC_URL:-http://localhost:8545}
OVM_GAS_ORACLE=0x420000000000000000000000000000000000000F
function send_tx() {
cast send --rpc-url $RPC_URL \
--private-key $PRIVATE_KEY \
--legacy \
--gas-price 0 \
$OVM_GAS_ORACLE \
$1 \
$2
}
function call() {
cast call --rpc-url $RPC_URL \
$OVM_GAS_ORACLE \
$1
}
echo "Scalar: $(call 'scalar()(uint256)')"
echo "L2 gas price: $(call 'gasPrice()(uint256)')"
echo "Overhead: $(call 'overhead()(uint256)')"
if [[ ! -z $PRIVATE_KEY ]]; then
if [[ ! -z $SCALAR ]]; then
echo "Setting scalar to $SCALAR"
send_tx 'setScalar(uint256)' $SCALAR
fi
if [[ ! -z $OVERHEAD ]]; then
echo "Setting overhead to $OVERHEAD"
send_tx 'setOverhead(uint256)' $OVERHEAD
fi
if [[ ! -z $L2_GAS_PRICE ]]; then
echo "Setting L2 gas price to $L2_GAS_PRICE"
send_tx 'setGasPrice(uint256)' $L2_GAS_PRICE
fi
fi
export * from './l2-gasprice'
export * from './set-owner'
export * from './take-dump'
export * from './validate-address-dictator'
......
/* Imports: External */
import { ethers } from 'ethers'
import { task } from 'hardhat/config'
import * as types from 'hardhat/internal/core/params/argumentTypes'
import { predeploys } from '../src/predeploys'
import { getContractDefinition } from '../src/contract-defs'
task('set-l2-gasprice')
.addOptionalParam(
'l2GasPrice',
'Gas Price to set on L2',
undefined,
types.int
)
.addOptionalParam('transactionGasPrice', 'tx.gasPrice', undefined, types.int)
.addOptionalParam(
'overhead',
'amortized additional gas used by each batch that users must pay for',
undefined,
types.int
)
.addOptionalParam(
'scalar',
'amount to scale up the gas to charge',
undefined,
types.int
)
.addOptionalParam(
'contractsRpcUrl',
'Sequencer HTTP Endpoint',
process.env.CONTRACTS_RPC_URL,
types.string
)
.addOptionalParam(
'contractsDeployerKey',
'Private Key',
process.env.CONTRACTS_DEPLOYER_KEY,
types.string
)
.setAction(async (args) => {
const provider = new ethers.providers.JsonRpcProvider(args.contractsRpcUrl)
const signer = new ethers.Wallet(args.contractsDeployerKey).connect(
provider
)
const GasPriceOracleArtifact = getContractDefinition('OVM_GasPriceOracle')
const GasPriceOracle = new ethers.Contract(
predeploys.OVM_GasPriceOracle,
GasPriceOracleArtifact.abi,
signer
)
const addr = await signer.getAddress()
console.log(`Using signer ${addr}`)
const owner = await GasPriceOracle.callStatic.owner()
if (owner !== addr) {
throw new Error(`Incorrect key. Owner ${owner}, Signer ${addr}`)
}
// List the current values
const gasPrice = await GasPriceOracle.callStatic.gasPrice()
const scalar = await GasPriceOracle.callStatic.scalar()
const overhead = await GasPriceOracle.callStatic.overhead()
console.log('Current values:')
console.log(`Gas Price: ${gasPrice.toString()}`)
console.log(`Scalar: ${scalar.toString()}`)
console.log(`Overhead: ${overhead.toString()}`)
if (args.l2GasPrice !== undefined) {
console.log(`Setting gas price to ${args.l2GasPrice}`)
const tx = await GasPriceOracle.connect(signer).setGasPrice(
args.l2GasPrice,
{ gasPrice: args.transactionGasPrice }
)
const receipt = await tx.wait()
console.log(`Success - ${receipt.transactionHash}`)
}
if (args.scalar !== undefined) {
console.log(`Setting scalar to ${args.scalar}`)
const tx = await GasPriceOracle.connect(signer).setScalar(args.scalar, {
gasPrice: args.transactionGasPrice,
})
const receipt = await tx.wait()
console.log(`Success - ${receipt.transactionHash}`)
}
if (args.overhead !== undefined) {
console.log(`Setting overhead to ${args.overhead}`)
const tx = await GasPriceOracle.connect(signer).setOverhead(
args.overhead,
{ gasPrice: args.transactionGasPrice }
)
const receipt = await tx.wait()
console.log(`Success - ${receipt.transactionHash}`)
}
})
/* External Imports */
import { ethers } from 'hardhat'
import { Contract, Signer, ContractFactory } from 'ethers'
import { Contract, Signer } from 'ethers'
/* Internal Imports */
import { expect } from '../../../setup'
import { NON_ZERO_ADDRESS } from '../../../helpers'
import { deploy, NON_ZERO_ADDRESS } from '../../../helpers'
describe('AddressDictator', () => {
let signer: Signer
let otherSigner: Signer
let signerAddress: string
let Factory__AddressDictator: ContractFactory
let Factory__Lib_AddressManager: ContractFactory
let signer1: Signer
let signer2: Signer
before(async () => {
;[signer, otherSigner] = await ethers.getSigners()
Factory__AddressDictator = await ethers.getContractFactory(
'AddressDictator'
)
Factory__Lib_AddressManager = await ethers.getContractFactory(
'Lib_AddressManager'
)
signerAddress = await signer.getAddress()
;[signer1, signer2] = await ethers.getSigners()
})
let AddressDictator: Contract
let Lib_AddressManager: Contract
beforeEach(async () => {
Lib_AddressManager = await Factory__Lib_AddressManager.connect(
signer
).deploy()
Lib_AddressManager = await deploy('Lib_AddressManager', {
signer: signer1,
})
AddressDictator = await Factory__AddressDictator.connect(signer).deploy(
Lib_AddressManager.address,
signerAddress,
['addr1'],
[NON_ZERO_ADDRESS]
)
AddressDictator = await deploy('AddressDictator', {
signer: signer1,
args: [
Lib_AddressManager.address,
await signer1.getAddress(),
['addr1'],
[NON_ZERO_ADDRESS],
],
})
Lib_AddressManager.transferOwnership(AddressDictator.address)
Lib_AddressManager.connect(signer1).transferOwnership(
AddressDictator.address
)
})
describe('initialize', () => {
it('should revert when providing wrong arguments', async () => {
await expect(
Factory__AddressDictator.connect(signer).deploy(
Lib_AddressManager.address,
signerAddress,
['addr1', 'addr2'],
[NON_ZERO_ADDRESS]
)
deploy('AddressDictator', {
signer: signer1,
args: [
Lib_AddressManager.address,
await signer1.getAddress(),
['addr1', 'addr2'],
[NON_ZERO_ADDRESS],
],
})
).to.be.revertedWith(
'AddressDictator: Must provide an equal number of names and addresses.'
)
......@@ -61,7 +54,7 @@ describe('AddressDictator', () => {
describe('setAddresses', async () => {
it('should change the addresses associated with a name', async () => {
await AddressDictator.setAddresses()
expect(await Lib_AddressManager.getAddress('addr1')).to.be.equal(
expect(await Lib_AddressManager.getAddress('addr1')).to.equal(
NON_ZERO_ADDRESS
)
})
......@@ -69,7 +62,7 @@ describe('AddressDictator', () => {
describe('getNamedAddresses', () => {
it('should return all the addresses and their names', async () => {
expect(await AddressDictator.getNamedAddresses()).to.be.deep.equal([
expect(await AddressDictator.getNamedAddresses()).to.deep.equal([
['addr1', NON_ZERO_ADDRESS],
])
})
......@@ -77,13 +70,13 @@ describe('AddressDictator', () => {
describe('returnOwnership', () => {
it('should transfer contract ownership to finalOwner', async () => {
await expect(AddressDictator.connect(signer).returnOwnership()).to.not.be
await expect(AddressDictator.connect(signer1).returnOwnership()).to.not.be
.reverted
})
it('should revert when called by non-owner', async () => {
await expect(
AddressDictator.connect(otherSigner).returnOwnership()
AddressDictator.connect(signer2).returnOwnership()
).to.be.revertedWith('AddressDictator: only callable by finalOwner')
})
})
......
/* External Imports */
import { ethers } from 'hardhat'
import { Contract, Signer, ContractFactory } from 'ethers'
import { Contract, Signer } from 'ethers'
/* Internal Imports */
import { expect } from '../../../setup'
import { deploy } from '../../../helpers'
describe('ChugSplashDictator', () => {
let signer: Signer
let otherSigner: Signer
let signerAddress: string
let Factory__L1ChugSplashProxy: ContractFactory
let Factory__ChugSplashDictator: ContractFactory
let signer1: Signer
let signer2: Signer
before(async () => {
;[signer, otherSigner] = await ethers.getSigners()
Factory__L1ChugSplashProxy = await ethers.getContractFactory(
'L1ChugSplashProxy'
)
Factory__ChugSplashDictator = await ethers.getContractFactory(
'ChugSplashDictator'
)
signerAddress = await signer.getAddress()
;[signer1, signer2] = await ethers.getSigners()
})
let L1ChugSplashProxy: Contract
let ChugSplashDictator: Contract
beforeEach(async () => {
L1ChugSplashProxy = await Factory__L1ChugSplashProxy.connect(signer).deploy(
signerAddress
)
L1ChugSplashProxy = await deploy('L1ChugSplashProxy', {
signer: signer1,
args: [await signer1.getAddress()],
})
ChugSplashDictator = await Factory__ChugSplashDictator.connect(
signer
).deploy(
L1ChugSplashProxy.address,
signerAddress,
ethers.utils.keccak256('0x1111'),
ethers.utils.keccak256('0x1234'),
ethers.utils.keccak256('0x5678'),
ethers.utils.keccak256('0x1234'),
ethers.utils.keccak256('0x1234')
)
ChugSplashDictator = await deploy('ChugSplashDictator', {
signer: signer1,
args: [
L1ChugSplashProxy.address,
await signer1.getAddress(),
ethers.utils.keccak256('0x1111'),
ethers.utils.keccak256('0x1234'),
ethers.utils.keccak256('0x5678'),
ethers.utils.keccak256('0x1234'),
ethers.utils.keccak256('0x1234'),
],
})
await L1ChugSplashProxy.connect(signer).setOwner(ChugSplashDictator.address)
await L1ChugSplashProxy.connect(signer1).setOwner(
ChugSplashDictator.address
)
})
describe('doActions', () => {
......@@ -56,20 +45,20 @@ describe('ChugSplashDictator', () => {
})
it('should set the proxy code, storage & owner', async () => {
await expect(ChugSplashDictator.connect(signer).doActions('0x1111')).to
await expect(ChugSplashDictator.connect(signer1).doActions('0x1111')).to
.not.be.reverted
})
})
describe('returnOwnership', () => {
it('should transfer contractc ownership to finalOwner', async () => {
await expect(ChugSplashDictator.connect(signer).returnOwnership()).to.not
await expect(ChugSplashDictator.connect(signer1).returnOwnership()).to.not
.be.reverted
})
it('should revert when called by non-owner', async () => {
await expect(
ChugSplashDictator.connect(otherSigner).returnOwnership()
ChugSplashDictator.connect(signer2).returnOwnership()
).to.be.revertedWith('ChugSplashDictator: only callable by finalOwner')
})
})
......
/* Imports: External */
import hre from 'hardhat'
import { Contract, Signer } from 'ethers'
import { smock } from '@defi-wonderland/smock'
/* Imports: Internal */
import { expect } from '../../setup'
import { getContractInterface } from '../../../src'
import { deploy } from '../../helpers'
describe('L1ChugSplashProxy', () => {
let signer1: Signer
......@@ -16,12 +15,9 @@ describe('L1ChugSplashProxy', () => {
let L1ChugSplashProxy: Contract
beforeEach(async () => {
const Factory__L1ChugSplashProxy = await hre.ethers.getContractFactory(
'L1ChugSplashProxy'
)
L1ChugSplashProxy = await Factory__L1ChugSplashProxy.deploy(
await signer1.getAddress()
)
L1ChugSplashProxy = await deploy('L1ChugSplashProxy', {
args: [await signer1.getAddress()],
})
})
describe('getOwner', () => {
......@@ -173,14 +169,16 @@ describe('L1ChugSplashProxy', () => {
const owner = await smock.fake<Contract>(
getContractInterface('iL1ChugSplashDeployer')
)
const factory = await hre.ethers.getContractFactory('L1ChugSplashProxy')
const proxy = await factory.deploy(owner.address)
L1ChugSplashProxy = await deploy('L1ChugSplashProxy', {
args: [owner.address],
})
owner.isUpgrading.returns(true)
await expect(
owner.wallet.sendTransaction({
to: proxy.address,
to: L1ChugSplashProxy.address,
data: '0x',
})
).to.be.revertedWith(
......
import hre from 'hardhat'
export const deploy = async (
name: string,
opts?: {
args?: any[]
signer?: any
}
) => {
const factory = await hre.ethers.getContractFactory(name, opts?.signer)
return factory.deploy(...(opts?.args || []))
}
export * from './eth-time'
export * from './deploy'
......@@ -20,29 +20,29 @@ export class DAIBridgeAdapter extends StandardBridgeAdapter {
[
{
inputs: [],
name: 'l1Token',
name: 'l1Token' as const,
outputs: [
{
internalType: 'address',
name: '',
type: 'address',
internalType: 'address' as const,
name: '' as const,
type: 'address' as const,
},
],
stateMutability: 'view',
type: 'function',
stateMutability: 'view' as const,
type: 'function' as const,
},
{
inputs: [],
name: 'l2Token',
name: 'l2Token' as const,
outputs: [
{
internalType: 'address',
name: '',
type: 'address',
internalType: 'address' as const,
name: '' as const,
type: 'address' as const,
},
],
stateMutability: 'view',
type: 'function',
stateMutability: 'view' as const,
type: 'function' as const,
},
],
this.messenger.l1Provider
......
......@@ -119,7 +119,7 @@ export class ETHBridgeAdapter extends StandardBridgeAdapter {
opts?: {
overrides?: Overrides
}
): Promise<TransactionRequest> => {
): Promise<never> => {
throw new Error(`approvals not necessary for ETH bridge`)
},
......
......@@ -109,7 +109,7 @@ export class CrossChainMessenger implements ICrossChainMessenger {
if (Provider.isProvider(this.l1SignerOrProvider)) {
return this.l1SignerOrProvider
} else {
return this.l1SignerOrProvider.provider as any
return this.l1SignerOrProvider.provider
}
}
......@@ -117,7 +117,7 @@ export class CrossChainMessenger implements ICrossChainMessenger {
if (Provider.isProvider(this.l2SignerOrProvider)) {
return this.l2SignerOrProvider
} else {
return this.l2SignerOrProvider.provider as any
return this.l2SignerOrProvider.provider
}
}
......@@ -144,10 +144,7 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} = {}
): Promise<CrossChainMessage[]> {
// Wait for the transaction receipt if the input is waitable.
// TODO: Maybe worth doing this with more explicit typing but whatever for now.
if (typeof (transaction as any).wait === 'function') {
await (transaction as any).wait()
}
await (transaction as TransactionResponse).wait?.()
// Convert the input to a transaction hash.
const txHash = toTransactionHash(transaction)
......@@ -821,7 +818,7 @@ export class CrossChainMessenger implements ICrossChainMessenger {
)
const stateTrieProof = await makeStateTrieProof(
this.l2Provider as any,
this.l2Provider as ethers.providers.JsonRpcProvider,
resolved.blockNumber,
this.contracts.l2.OVM_L2ToL1MessagePasser.address,
messageSlot
......
......@@ -83,4 +83,10 @@ export type L2Provider<TProvider extends Provider> = TProvider & {
* @returns Estimated total gas cost.
*/
estimateTotalGasCost(tx: TransactionRequest): Promise<BigNumber>
/**
* Internal property to determine if a provider is a L2Provider
* You are likely looking for the isL2Provider function
*/
_isL2Provider: true
}
......@@ -9,6 +9,16 @@ import { Contract, BigNumber } from 'ethers'
import { ICrossChainMessenger } from './cross-chain-messenger'
import { IBridgeAdapter } from './bridge-adapter'
/**
* Commonly used Chain IDs
*/
export enum Chain {
MAINNET = 1,
GOERLI = 5,
KOVAN = 42,
HARDHAT_LOCAL = 31337,
}
/**
* L1 contract references.
*/
......
import assert from 'assert'
import { Provider, TransactionRequest } from '@ethersproject/abstract-provider'
import { serialize } from '@ethersproject/transactions'
import { Contract, BigNumber } from 'ethers'
......@@ -7,6 +9,8 @@ import cloneDeep from 'lodash/cloneDeep'
import { L2Provider, ProviderLike, NumberLike } from './interfaces'
import { toProvider, toNumber, toBigNumber } from './utils'
type ProviderTypeIsWrong = any
/**
* Returns a Contract object for the GasPriceOracle.
*
......@@ -115,6 +119,24 @@ export const estimateTotalGasCost = async (
return l1GasCost.add(l2GasCost)
}
/**
* Determines if a given Provider is an L2Provider. Will coerce type
* if true
*
* @param provider The provider to check
* @returns Boolean
* @example
* if (isL2Provider(provider)) {
* // typescript now knows it is of type L2Provider
* const gasPrice = await provider.estimateL2GasPrice(tx)
* }
*/
export const isL2Provider = <TProvider extends Provider>(
provider: TProvider
): provider is L2Provider<TProvider> => {
return Boolean((provider as L2Provider<TProvider>)._isL2Provider)
}
/**
* Returns an provider wrapped as an Optimism L2 provider. Adds a few extra helper functions to
* simplify the process of estimating the gas usage for a transaction on Optimism. Returns a COPY
......@@ -126,22 +148,21 @@ export const estimateTotalGasCost = async (
export const asL2Provider = <TProvider extends Provider>(
provider: TProvider
): L2Provider<TProvider> => {
// Make a copy of the provider since we'll be modifying some internals and don't want to mess
// with the original object.
const l2Provider = cloneDeep(provider) as any
// Skip if we've already wrapped this provider.
if (l2Provider._isL2Provider) {
return l2Provider
if (isL2Provider(provider)) {
return provider
}
// Make a copy of the provider since we'll be modifying some internals and don't want to mess
// with the original object.
const l2Provider = cloneDeep(provider) as L2Provider<TProvider>
// Not exactly sure when the provider wouldn't have a formatter function, but throw an error if
// it doesn't have one. The Provider type doesn't define it but every provider I've dealt with
// seems to have it.
const formatter = l2Provider.formatter
if (formatter === undefined) {
throw new Error(`provider.formatter must be defined`)
}
// TODO this may be fixed if library has gotten updated since
const formatter = (l2Provider as ProviderTypeIsWrong).formatter
assert(formatter, `provider.formatter must be defined`)
// Modify the block formatter to return the state root. Not strictly related to Optimism, just a
// generally useful thing that really should've been on the Ethers block object to begin with.
......
import { Chain } from '../interfaces'
export const DEPOSIT_CONFIRMATION_BLOCKS = {
// Mainnet
1: 50,
// Goerli
5: 12,
// Kovan
42: 12,
// Hardhat Local
[Chain.MAINNET]: 50 as const,
[Chain.GOERLI]: 12 as const,
[Chain.KOVAN]: 12 as const,
// 2 just for testing purposes
31337: 2,
[Chain.HARDHAT_LOCAL]: 2 as const,
}
export const CHAIN_BLOCK_TIMES = {
// Mainnet
1: 13,
// Goerli
5: 15,
// Kovan
42: 4,
// Hardhat Local
31337: 1,
[Chain.MAINNET]: 13 as const,
[Chain.GOERLI]: 15 as const,
[Chain.KOVAN]: 4 as const,
[Chain.HARDHAT_LOCAL]: 1 as const,
}
......@@ -29,9 +29,9 @@ export const toSignerOrProvider = (
if (typeof signerOrProvider === 'string') {
return new ethers.providers.JsonRpcProvider(signerOrProvider)
} else if (Provider.isProvider(signerOrProvider)) {
return signerOrProvider as Provider
return signerOrProvider
} else if (Signer.isSigner(signerOrProvider)) {
return signerOrProvider as Signer
return signerOrProvider
} else {
throw new Error('Invalid provider')
}
......@@ -48,7 +48,7 @@ export const toProvider = (provider: ProviderLike): Provider => {
if (typeof provider === 'string') {
return new ethers.providers.JsonRpcProvider(provider)
} else if (Provider.isProvider(provider)) {
return provider as Provider
return provider
} else {
throw new Error('Invalid provider')
}
......@@ -66,7 +66,6 @@ export const toTransactionHash = (transaction: TransactionLike): string => {
ethers.utils.isHexString(transaction, 32),
'Invalid transaction hash'
)
return transaction
} else if ((transaction as TransactionReceipt).transactionHash) {
return (transaction as TransactionReceipt).transactionHash
......
......@@ -13,6 +13,7 @@ import {
BridgeAdapters,
BridgeAdapterData,
ICrossChainMessenger,
Chain,
} from '../interfaces'
import {
StandardBridgeAdapter,
......@@ -40,9 +41,9 @@ export const DEFAULT_L2_CONTRACT_ADDRESSES: OEL2ContractsLike = {
* back to the original contract names so we can look them up.
*/
const NAME_REMAPPING = {
AddressManager: 'Lib_AddressManager',
OVM_L1BlockNumber: 'iOVM_L1BlockNumber',
WETH: 'WETH9',
AddressManager: 'Lib_AddressManager' as const,
OVM_L1BlockNumber: 'iOVM_L1BlockNumber' as const,
WETH: 'WETH9' as const,
}
/**
......@@ -53,51 +54,59 @@ const NAME_REMAPPING = {
export const CONTRACT_ADDRESSES: {
[l1ChainId: number]: OEContractsLike
} = {
// Mainnet
1: {
[Chain.MAINNET]: {
l1: {
AddressManager: '0xdE1FCfB0851916CA5101820A69b13a4E276bd81F',
L1CrossDomainMessenger: '0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1',
L1StandardBridge: '0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1',
StateCommitmentChain: '0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19',
CanonicalTransactionChain: '0x5E4e65926BA27467555EB562121fac00D24E9dD2',
BondManager: '0xcd626E1328b41fCF24737F137BcD4CE0c32bc8d1',
AddressManager: '0xdE1FCfB0851916CA5101820A69b13a4E276bd81F' as const,
L1CrossDomainMessenger:
'0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1' as const,
L1StandardBridge: '0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1' as const,
StateCommitmentChain:
'0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19' as const,
CanonicalTransactionChain:
'0x5E4e65926BA27467555EB562121fac00D24E9dD2' as const,
BondManager: '0xcd626E1328b41fCF24737F137BcD4CE0c32bc8d1' as const,
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
},
// Kovan
42: {
[Chain.KOVAN]: {
l1: {
AddressManager: '0x100Dd3b414Df5BbA2B542864fF94aF8024aFdf3a',
L1CrossDomainMessenger: '0x4361d0F75A0186C05f971c566dC6bEa5957483fD',
L1StandardBridge: '0x22F24361D548e5FaAfb36d1437839f080363982B',
StateCommitmentChain: '0xD7754711773489F31A0602635f3F167826ce53C5',
CanonicalTransactionChain: '0xf7B88A133202d41Fe5E2Ab22e6309a1A4D50AF74',
BondManager: '0xc5a603d273E28185c18Ba4d26A0024B2d2F42740',
AddressManager: '0x100Dd3b414Df5BbA2B542864fF94aF8024aFdf3a' as const,
L1CrossDomainMessenger:
'0x4361d0F75A0186C05f971c566dC6bEa5957483fD' as const,
L1StandardBridge: '0x22F24361D548e5FaAfb36d1437839f080363982B' as const,
StateCommitmentChain:
'0xD7754711773489F31A0602635f3F167826ce53C5' as const,
CanonicalTransactionChain:
'0xf7B88A133202d41Fe5E2Ab22e6309a1A4D50AF74' as const,
BondManager: '0xc5a603d273E28185c18Ba4d26A0024B2d2F42740' as const,
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
},
// Goerli
5: {
[Chain.GOERLI]: {
l1: {
AddressManager: '0x2F7E3cAC91b5148d336BbffB224B4dC79F09f01D',
L1CrossDomainMessenger: '0xEcC89b9EDD804850C4F343A278Be902be11AaF42',
L1StandardBridge: '0x73298186A143a54c20ae98EEE5a025bD5979De02',
StateCommitmentChain: '0x1afcA918eff169eE20fF8AB6Be75f3E872eE1C1A',
CanonicalTransactionChain: '0x2ebA8c4EfDB39A8Cd8f9eD65c50ec079f7CEBD81',
BondManager: '0xE5AE60bD6F8DEe4D0c2BC9268e23B92F1cacC58F',
AddressManager: '0x2F7E3cAC91b5148d336BbffB224B4dC79F09f01D' as const,
L1CrossDomainMessenger:
'0xEcC89b9EDD804850C4F343A278Be902be11AaF42' as const,
L1StandardBridge: '0x73298186A143a54c20ae98EEE5a025bD5979De02' as const,
StateCommitmentChain:
'0x1afcA918eff169eE20fF8AB6Be75f3E872eE1C1A' as const,
CanonicalTransactionChain:
'0x2ebA8c4EfDB39A8Cd8f9eD65c50ec079f7CEBD81' as const,
BondManager: '0xE5AE60bD6F8DEe4D0c2BC9268e23B92F1cacC58F' as const,
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
},
// Hardhat local
31337: {
[Chain.HARDHAT_LOCAL]: {
l1: {
AddressManager: '0x5FbDB2315678afecb367f032d93F642f64180aa3',
L1CrossDomainMessenger: '0x8A791620dd6260079BF849Dc5567aDC3F2FdC318',
L1StandardBridge: '0x610178dA211FEF7D417bC0e6FeD39F05609AD788',
StateCommitmentChain: '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9',
CanonicalTransactionChain: '0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9',
BondManager: '0x5FC8d32690cc91D4c39d9d3abcBD16989F875707',
AddressManager: '0x5FbDB2315678afecb367f032d93F642f64180aa3' as const,
L1CrossDomainMessenger:
'0x8A791620dd6260079BF849Dc5567aDC3F2FdC318' as const,
L1StandardBridge: '0x610178dA211FEF7D417bC0e6FeD39F05609AD788' as const,
StateCommitmentChain:
'0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9' as const,
CanonicalTransactionChain:
'0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9' as const,
BondManager: '0x5FC8d32690cc91D4c39d9d3abcBD16989F875707' as const,
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
},
......@@ -111,7 +120,7 @@ export const BRIDGE_ADAPTER_DATA: {
} = {
// TODO: Maybe we can pull these automatically from the token list?
// Alternatively, check against the token list in CI.
1: {
[Chain.MAINNET]: {
Standard: {
Adapter: StandardBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[1].l1.L1StandardBridge,
......@@ -124,16 +133,16 @@ export const BRIDGE_ADAPTER_DATA: {
},
BitBTC: {
Adapter: StandardBridgeAdapter,
l1Bridge: '0xaBA2c5F108F7E820C049D5Af70B16ac266c8f128',
l2Bridge: '0x158F513096923fF2d3aab2BcF4478536de6725e2',
l1Bridge: '0xaBA2c5F108F7E820C049D5Af70B16ac266c8f128' as const,
l2Bridge: '0x158F513096923fF2d3aab2BcF4478536de6725e2' as const,
},
DAI: {
Adapter: DAIBridgeAdapter,
l1Bridge: '0x10E6593CDda8c58a1d0f14C5164B376352a55f2F',
l2Bridge: '0x467194771dAe2967Aef3ECbEDD3Bf9a310C76C65',
l1Bridge: '0x10E6593CDda8c58a1d0f14C5164B376352a55f2F' as const,
l2Bridge: '0x467194771dAe2967Aef3ECbEDD3Bf9a310C76C65' as const,
},
},
42: {
[Chain.KOVAN]: {
Standard: {
Adapter: StandardBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[42].l1.L1StandardBridge,
......@@ -146,21 +155,21 @@ export const BRIDGE_ADAPTER_DATA: {
},
BitBTC: {
Adapter: StandardBridgeAdapter,
l1Bridge: '0x0b651A42F32069d62d5ECf4f2a7e5Bd3E9438746',
l2Bridge: '0x0CFb46528a7002a7D8877a5F7a69b9AaF1A9058e',
l1Bridge: '0x0b651A42F32069d62d5ECf4f2a7e5Bd3E9438746' as const,
l2Bridge: '0x0CFb46528a7002a7D8877a5F7a69b9AaF1A9058e' as const,
},
USX: {
Adapter: StandardBridgeAdapter,
l1Bridge: '0x40E862341b2416345F02c41Ac70df08525150dC7',
l2Bridge: '0xB4d37826b14Cd3CB7257A2A5094507d701fe715f',
l1Bridge: '0x40E862341b2416345F02c41Ac70df08525150dC7' as const,
l2Bridge: '0xB4d37826b14Cd3CB7257A2A5094507d701fe715f' as const,
},
DAI: {
Adapter: DAIBridgeAdapter,
l1Bridge: '0xb415e822C4983ecD6B1c1596e8a5f976cf6CD9e3',
l2Bridge: '0x467194771dAe2967Aef3ECbEDD3Bf9a310C76C65',
l1Bridge: '0xb415e822C4983ecD6B1c1596e8a5f976cf6CD9e3' as const,
l2Bridge: '0x467194771dAe2967Aef3ECbEDD3Bf9a310C76C65' as const,
},
},
5: {
[Chain.GOERLI]: {
Standard: {
Adapter: StandardBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[5].l1.L1StandardBridge,
......@@ -172,7 +181,7 @@ export const BRIDGE_ADAPTER_DATA: {
l2Bridge: predeploys.L2StandardBridge,
},
},
31337: {
[Chain.HARDHAT_LOCAL]: {
Standard: {
Adapter: StandardBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[31337].l1.L1StandardBridge,
......@@ -274,21 +283,29 @@ export const getAllOEContracts = (
}
// Attach all L1 contracts.
const l1Contracts: OEL1Contracts = {} as any
const l1Contracts = {} as OEL1Contracts
for (const [contractName, contractAddress] of Object.entries(addresses.l1)) {
l1Contracts[contractName] = getOEContract(contractName as any, l1ChainId, {
address: opts.overrides?.l1?.[contractName] || contractAddress,
signerOrProvider: opts.l1SignerOrProvider,
})
l1Contracts[contractName] = getOEContract(
contractName as keyof OEL1Contracts,
l1ChainId,
{
address: opts.overrides?.l1?.[contractName] || contractAddress,
signerOrProvider: opts.l1SignerOrProvider,
}
)
}
// Attach all L2 contracts.
const l2Contracts: OEL2Contracts = {} as any
const l2Contracts = {} as OEL2Contracts
for (const [contractName, contractAddress] of Object.entries(addresses.l2)) {
l2Contracts[contractName] = getOEContract(contractName as any, l1ChainId, {
address: opts.overrides?.l2?.[contractName] || contractAddress,
signerOrProvider: opts.l2SignerOrProvider,
})
l2Contracts[contractName] = getOEContract(
contractName as keyof OEL2Contracts,
l1ChainId,
{
address: opts.overrides?.l2?.[contractName] || contractAddress,
signerOrProvider: opts.l2SignerOrProvider,
}
)
}
return {
......
......@@ -8,10 +8,13 @@
* @param keys Keys to omit from the returned object.
* @returns A copy of the given object with the given keys omitted.
*/
export const omit = (obj: any, ...keys: string[]) => {
export const omit = <T extends object, K extends string | number | symbol>(
obj: T,
...keys: K[]
): Omit<T, K> => {
const copy = { ...obj }
for (const key of keys) {
delete copy[key]
delete copy[key as string]
}
return copy
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment