Commit 3c188103 authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

Merge pull request #2845 from ethereum-optimism/develop

Merge develop into master
parents 3cbf56d3 df5eb9e7
---
'@eth-optimism/contracts-bedrock': patch
---
Separate the owner and sequencer roles in the OutputOracle
---
'@eth-optimism/contracts-bedrock': patch
---
Fix bug in bedrock deploy scripts
---
'@eth-optimism/contracts-bedrock': patch
---
Add genesis script
---
'@eth-optimism/contracts-bedrock': minor
---
Add separate sequencer role to Oracle
---
'@eth-optimism/sdk': minor
---
Have SDK use L2 chain ID as the source of truth.
---
'@eth-optimism/contracts-bedrock': patch
---
Fix order of args to L2OO constructor
---
'@eth-optimism/core-utils': minor
---
Update geth's Genesis type to work with modern geth
---
'@eth-optimism/contracts-bedrock': patch
---
Fix for incorrect constructor args in deploy config
---
'@eth-optimism/integration-tests': patch
'@eth-optimism/contracts-governance': patch
'@eth-optimism/fault-detector': patch
'@eth-optimism/message-relayer': patch
---
Update SDK version and usage to account for new constructor
---
'@eth-optimism/contracts-bedrock': patch
---
Make the output oracle upgradeable.
---
'@eth-optimism/fault-detector': patch
---
Fix bug where FD would try to sync beyond local tip
---
'@eth-optimism/go-builder': patch
---
Upgrade golangci-lint version for go 1.18
---
'@eth-optimism/common-ts': minor
---
Add version to healthz for convenience
......@@ -410,6 +410,10 @@ jobs:
forge --version
forge snapshot --check
working_directory: packages/contracts-bedrock
- run:
name: storage snapshot
command: yarn storage-snapshot && git diff --exit-code .storage-layout
working_directory: packages/contracts-bedrock
- run:
name: check go bindings
command: make && git diff --exit-code
......
......@@ -7,6 +7,10 @@ coverage.json
*.tsbuildinfo
yarn-error.log
.yarn/*
!.yarn/releases
!.yarn/plugins
.pnp.*
dist
artifacts
......
This source diff could not be displayed because it is too large. You can view the blob instead.
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
yarn-path ".yarn/releases/yarn-1.22.19.cjs"
......@@ -3,7 +3,6 @@ COMPOSE_FILE=replica.yml:replica-shared.yml:replica-toml.yml
ETH_NETWORK=kovan
DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT=WONT_WORK_UNLESS_YOU_PROVIDE_A_VALID_ETHEREUM_L1_ENDPOINT
DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT=https://kovan.optimism.io
REPLICA_HEALTHCHECK__ETH_NETWORK_RPC_PROVIDER=https://kovan.optimism.io
SEQUENCER_CLIENT_HTTP=https://kovan.optimism.io
SHARED_ENV_PATH=../envs/kovan
GCMODE=archive
......@@ -14,5 +13,7 @@ L2GETH_HTTP_PORT=9991
L2GETH_WS_PORT=9992
DTL_PORT=7878
GETH_INIT_SCRIPT=check-for-chaindata-berlin.sh
HEALTHCHECK__REFERENCE_RPC_PROVIDER=https://kovan.optimism.io
HEALTHCHECK__TARGET_RPC_PROVIDER=http://l2geth-replica:8545
RESTART=unless-stopped
......@@ -2,18 +2,19 @@ COMPOSE_PROJECT_NAME=op-replica
COMPOSE_FILE=replica.yml:replica-shared.yml:replica-toml.yml
ETH_NETWORK=mainnet
DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT=WONT_WORK_UNLESS_YOU_PROVIDE_A_VALID_ETHEREUM_L1_ENDPOINT
DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT=https://mainnet.optimism.io
REPLICA_HEALTHCHECK__ETH_NETWORK_RPC_PROVIDER=https://mainnet.optimism.io
DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT=<infra-provider-l2-endpoint>
SEQUENCER_CLIENT_HTTP=https://mainnet.optimism.io
SHARED_ENV_PATH=../envs/mainnet
GCMODE=archive
L2GETH_IMAGE_TAG=0.5.14
DTL_IMAGE_TAG=0.5.21
L2GETH_IMAGE_TAG=0.5.22
DTL_IMAGE_TAG=0.5.36
HC_IMAGE_TAG=1.0.6
L2GETH_HTTP_PORT=9991
L2GETH_WS_PORT=9992
DTL_PORT=7878
GETH_INIT_SCRIPT=check-for-chaindata-berlin.sh
HEALTHCHECK__REFERENCE_RPC_PROVIDER=<infra-provider-l2-endpoiont>
HEALTHCHECK__TARGET_RPC_PROVIDER=http://l2geth-replica:8545
RESTART=unless-stopped
......@@ -22,4 +23,4 @@ ROLLUP_BACKEND=l2
DATA_TRANSPORT_LAYER__DEFAULT_BACKEND=l2
DATA_TRANSPORT_LAYER__L1_GAS_PRICE_BACKEND=l2
DATA_TRANSPORT_LAYER__SYNC_FROM_L1=false
DATA_TRANSPORT_LAYER__SYNC_FROM_L2=true
\ No newline at end of file
DATA_TRANSPORT_LAYER__SYNC_FROM_L2=true
......@@ -8,9 +8,6 @@ configMapGenerator:
- name: l2geth-replica
envs:
- ./l2geth-replica.env
- name: replica-healthcheck
envs:
- ./replica-healthcheck.env
- name: geth-scripts
files:
- ./check-for-chaindata.sh
\ No newline at end of file
REPLICA_HEALTHCHECK__ETH_NETWORK=goerli-nightly
REPLICA_HEALTHCHECK__L2GETH_IMAGE_TAG=0.4.9
REPLICA_HEALTHCHECK__ETH_REPLICA_RPC_PROVIDER=http://l2geth-replica:8545
\ No newline at end of file
......@@ -8,6 +8,3 @@ configMapGenerator:
- name: l2geth-replica
envs:
- ./l2geth-replica.env
- name: replica-healthcheck
envs:
- ./replica-healthcheck.env
REPLICA_HEALTHCHECK__ETH_NETWORK=kovan
REPLICA_HEALTHCHECK__L2GETH_IMAGE_TAG=0.4.9
REPLICA_HEALTHCHECK__ETH_NETWORK_RPC_PROVIDER=http://sequencer.default:8545
REPLICA_HEALTHCHECK__ETH_REPLICA_RPC_PROVIDER=http://l2geth-replica:8545
\ No newline at end of file
......@@ -8,6 +8,3 @@ configMapGenerator:
- name: l2geth-replica
envs:
- ./l2geth-replica.env
- name: replica-healthcheck
envs:
- ./replica-healthcheck.env
REPLICA_HEALTHCHECK__ETH_NETWORK=mainnet
REPLICA_HEALTHCHECK__L2GETH_IMAGE_TAG=0.4.8
REPLICA_HEALTHCHECK__ETH_NETWORK_RPC_PROVIDER=http://sequencer.default:8545
REPLICA_HEALTHCHECK__ETH_REPLICA_RPC_PROVIDER=http://l2geth-replica:8545
\ No newline at end of file
......@@ -4,7 +4,7 @@ import {
TransactionResponse,
TransactionReceipt,
} from '@ethersproject/providers'
import { sleep } from '@eth-optimism/core-utils'
import { getChainId, sleep } from '@eth-optimism/core-utils'
import {
CrossChainMessenger,
MessageStatus,
......@@ -58,8 +58,6 @@ export class OptimismEnv {
}
static async new(): Promise<OptimismEnv> {
const network = await l1Provider.getNetwork()
let bridgeOverrides: BridgeAdapterData
if (envConfig.L1_STANDARD_BRIDGE) {
bridgeOverrides = {
......@@ -79,7 +77,8 @@ export class OptimismEnv {
const messenger = new CrossChainMessenger({
l1SignerOrProvider: l1Wallet,
l2SignerOrProvider: l2Wallet,
l1ChainId: network.chainId,
l1ChainId: await getChainId(l1Provider),
l2ChainId: await getChainId(l2Provider),
contracts: {
l1: {
AddressManager: envConfig.ADDRESS_MANAGER,
......
......@@ -1391,6 +1391,7 @@ func TestFakedSyncProgress64Fast(t *testing.T) { testFakedSyncProgress(t, 64, F
func TestFakedSyncProgress64Light(t *testing.T) { testFakedSyncProgress(t, 64, LightSync) }
func testFakedSyncProgress(t *testing.T, protocol int, mode SyncMode) {
t.Skip("Flakey tests unused by Optimism")
t.Parallel()
tester := newTester()
......
......@@ -36,8 +36,8 @@ type L2OutputOracleOutputProposal struct {
// L2OutputOracleMetaData contains all meta data concerning the L2OutputOracle contract.
var L2OutputOracleMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_submissionInterval\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_genesisL2Output\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_historicalTotalBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockTime\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_sequencer\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_l2Output\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l1Timestamp\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"L2OutputAppended\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_l2Output\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l1Timestamp\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"L2OutputDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"HISTORICAL_TOTAL_BLOCKS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_BLOCK_TIME\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"STARTING_BLOCK_NUMBER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"STARTING_TIMESTAMP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SUBMISSION_INTERVAL\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_l2Output\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_l1Blockhash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l1BlockNumber\",\"type\":\"uint256\"}],\"name\":\"appendL2Output\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"computeL2Timestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"internalType\":\"structL2OutputOracle.OutputProposal\",\"name\":\"_proposal\",\"type\":\"tuple\"}],\"name\":\"deleteL2Output\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"getL2Output\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"internalType\":\"structL2OutputOracle.OutputProposal\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
Bin: "0x61012060405234801561001157600080fd5b5060405161112c38038061112c8339810160408190526100309161016f565b6100393361011f565b4282106100be5760405162461bcd60e51b815260206004820152604360248201527f4f7574707574204f7261636c653a20496e697469616c204c3220626c6f636b2060448201527f74696d65206d757374206265206c657373207468616e2063757272656e742074606482015262696d6560e81b608482015260a40160405180910390fd5b608087905260a085905260c084905260e083905261010082905260408051808201825287815242602080830191825260008881526002909152929092209051815590516001918201558490556101138161011f565b505050505050506101de565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080600080600080600060e0888a03121561018a57600080fd5b8751602089015160408a015160608b015160808c015160a08d015160c08e0151959c50939a509198509650945092506001600160a01b03811681146101ce57600080fd5b8091505092959891949750929550565b60805160a05160c05160e05161010051610ee161024b600039600060f301526000818161015c0152610b370152600081816101b901528181610a080152610b02015260006102df0152600081816101ed015281816105cc01528181610ade0152610b650152610ee16000f3fe6080604052600436106100dc5760003560e01c8063715018a61161007f578063a4771aad11610059578063a4771aad146102cd578063d1de856c14610301578063dcec334814610321578063f2fde38b1461033657600080fd5b8063715018a61461020f5780638da5cb5b14610224578063a25ae5571461025957600080fd5b806325188104116100bb578063251881041461017e5780634599c788146101915780634ab65d73146101a7578063529933df146101db57600080fd5b80622134cc146100e1578063093b3d901461012857806320e9fcd41461014a575b600080fd5b3480156100ed57600080fd5b506101157f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561013457600080fd5b50610148610143366004610d3b565b610356565b005b34801561015657600080fd5b506101157f000000000000000000000000000000000000000000000000000000000000000081565b61014861018c366004610db1565b6105f8565b34801561019d57600080fd5b5061011560015481565b3480156101b357600080fd5b506101157f000000000000000000000000000000000000000000000000000000000000000081565b3480156101e757600080fd5b506101157f000000000000000000000000000000000000000000000000000000000000000081565b34801561021b57600080fd5b50610148610977565b34801561023057600080fd5b5060005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011f565b34801561026557600080fd5b506102b2610274366004610de3565b604080518082019091526000808252602082015250600090815260026020908152604091829020825180840190935280548352600101549082015290565b6040805182518152602092830151928101929092520161011f565b3480156102d957600080fd5b506101157f000000000000000000000000000000000000000000000000000000000000000081565b34801561030d57600080fd5b5061011561031c366004610de3565b610a04565b34801561032d57600080fd5b50610115610b61565b34801561034257600080fd5b50610148610351366004610dfc565b610b96565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b60018054600090815260026020908152604091829020825180840190935280548084529301549082015282519091146104bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605260248201527f4f75747075744f7261636c653a20546865206f757470757420726f6f7420746f60448201527f2064656c65746520646f6573206e6f74206d6174636820746865206c6174657360648201527f74206f75747075742070726f706f73616c2e0000000000000000000000000000608482015260a4016103d3565b806020015182602001511461057a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f4f75747075744f7261636c653a205468652074696d657374616d7020746f206460448201527f656c65746520646f6573206e6f74206d6174636820746865206c61746573742060648201527f6f75747075742070726f706f73616c2e00000000000000000000000000000000608482015260a4016103d3565b600154602082015182516040517f7320566fd5256cf8923648a5d9f560f1e92f1435a1bb32ddd1fe107f224ad35990600090a4600180546000908152600260205260408120818155820155546105f1907f000000000000000000000000000000000000000000000000000000000000000090610e68565b6001555050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610679576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103d3565b610681610b61565b8314610735576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604760248201527f4f75747075744f7261636c653a20426c6f636b206e756d626572206d7573742060448201527f626520657175616c20746f206e65787420657870656374656420626c6f636b2060648201527f6e756d6265722e00000000000000000000000000000000000000000000000000608482015260a4016103d3565b4261073f84610a04565b106107cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4f75747075744f7261636c653a2043616e6e6f7420617070656e64204c32206f60448201527f757470757420696e206675747572652e0000000000000000000000000000000060648201526084016103d3565b83610859576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4f75747075744f7261636c653a2043616e6e6f74207375626d697420656d707460448201527f79204c32206f75747075742e000000000000000000000000000000000000000060648201526084016103d3565b81156109155781814014610915576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604760248201527f4f75747075744f7261636c653a20426c6f636b6861736820646f6573206e6f7460448201527f206d61746368207468652068617368206174207468652065787065637465642060648201527f6865696768742e00000000000000000000000000000000000000000000000000608482015260a4016103d3565b60408051808201825285815242602080830182815260008881526002909252848220935184555160019384015591869055915185929187917fd6703ded1701060d9ae1793db76d594790a4e775781225f79b5aa8a77987c0809190a450505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103d3565b610a026000610cc6565b565b60007f0000000000000000000000000000000000000000000000000000000000000000821015610adc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605660248201527f4f75747075744f7261636c653a20426c6f636b206e756d626572206d7573742060448201527f62652067726561746572207468616e206f7220657175616c20746f207468652060648201527f7374617274696e6720626c6f636b206e756d6265722e00000000000000000000608482015260a4016103d3565b7f0000000000000000000000000000000000000000000000000000000000000000610b277f000000000000000000000000000000000000000000000000000000000000000084610e68565b610b319190610e7f565b610b5b907f0000000000000000000000000000000000000000000000000000000000000000610ebc565b92915050565b60007f0000000000000000000000000000000000000000000000000000000000000000600154610b919190610ebc565b905090565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103d3565b73ffffffffffffffffffffffffffffffffffffffff8116610cba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103d3565b610cc381610cc6565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060408284031215610d4d57600080fd5b6040516040810181811067ffffffffffffffff82111715610d97577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052823581526020928301359281019290925250919050565b60008060008060808587031215610dc757600080fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215610df557600080fd5b5035919050565b600060208284031215610e0e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610e3257600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015610e7a57610e7a610e39565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610eb757610eb7610e39565b500290565b60008219821115610ecf57610ecf610e39565b50019056fea164736f6c634300080a000a",
ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_submissionInterval\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_genesisL2Output\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_historicalTotalBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startingTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockTime\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_sequencer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_l2Output\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l1Timestamp\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"L2OutputAppended\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_l2Output\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l1Timestamp\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"L2OutputDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousSequencer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newSequencer\",\"type\":\"address\"}],\"name\":\"SequencerChanged\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"HISTORICAL_TOTAL_BLOCKS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_BLOCK_TIME\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_OUTPUT_ORACLE_VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"STARTING_BLOCK_NUMBER\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"STARTING_TIMESTAMP\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SUBMISSION_INTERVAL\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_l2Output\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"_l1Blockhash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_l1BlockNumber\",\"type\":\"uint256\"}],\"name\":\"appendL2Output\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newSequencer\",\"type\":\"address\"}],\"name\":\"changeSequencer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"computeL2Timestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"internalType\":\"structL2OutputOracle.OutputProposal\",\"name\":\"_proposal\",\"type\":\"tuple\"}],\"name\":\"deleteL2Output\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"getL2Output\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"internalType\":\"structL2OutputOracle.OutputProposal\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_genesisL2Output\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_startingBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_sequencer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sequencer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
Bin: "0x6101206040523480156200001257600080fd5b5060405162001d7f38038062001d7f8339810160408190526200003591620005c8565b428310620000bc5760405162461bcd60e51b815260206004820152604360248201527f4f7574707574204f7261636c653a20496e697469616c204c3220626c6f636b2060448201527f74696d65206d757374206265206c657373207468616e2063757272656e742074606482015262696d6560e81b608482015260a4015b60405180910390fd5b608088905260a086905260c085905260e0849052610100839052620000e487868484620000f2565b50505050505050506200063a565b600160006200010182620001bf565b905080156200011a576000805461ff0019166101001790555b6040805180820182528781524260208083019182526000898152606790915292909220905181559051600190910155606685905562000158620002d2565b62000163846200033a565b6200016e83620004e8565b8015620001b7576000805461ff001916905560405160ff831681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60008054610100900460ff161562000254578160ff166001148015620001f85750620001f6306200053a60201b620011491760201c565b155b6200024c5760405162461bcd60e51b815260206004820152602e602482015260008051602062001d3f83398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000b3565b506000919050565b60005460ff808416911610620002b35760405162461bcd60e51b815260206004820152602e602482015260008051602062001d3f83398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000b3565b506000805460ff191660ff92909216919091179055600190565b919050565b600054610100900460ff166200032e5760405162461bcd60e51b815260206004820152602b602482015260008051602062001d5f83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000b3565b6200033862000549565b565b6033546001600160a01b03163314620003965760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620000b3565b6001600160a01b038116620004065760405162461bcd60e51b815260206004820152602f60248201527f4f75747075744f7261636c653a206e65772073657175656e636572206973207460448201526e6865207a65726f206164647265737360881b6064820152608401620000b3565b6033546001600160a01b03828116911614156200048c5760405162461bcd60e51b815260206004820152603360248201527f4f75747075744f7261636c653a2073657175656e6365722063616e6e6f74206260448201527f652073616d6520617320746865206f776e6572000000000000000000000000006064820152608401620000b3565b6065546040516001600160a01b038084169216907f6ec88bae255aa7e73521c3beb17e9bc7940169e669440c5531733c0d2e91110d90600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03163b151590565b600054610100900460ff16620005a55760405162461bcd60e51b815260206004820152602b602482015260008051602062001d5f83398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000b3565b6200033833620004e8565b80516001600160a01b0381168114620002cd57600080fd5b600080600080600080600080610100898b031215620005e657600080fd5b885197506020890151965060408901519550606089015194506080890151935060a089015192506200061b60c08a01620005b0565b91506200062b60e08a01620005b0565b90509295985092959890939650565b60805160a05160c05160e05161010051611696620006a9600039600061013f0152600081816101a80152610ebd01526000818161022501528181610d8e0152610e88015260006103ba015260008181610259015281816106cb01528181610e640152610fe801526116966000f3fe6080604052600436106101285760003560e01c8063715018a6116100a5578063a4771aad11610074578063d20b1a5111610059578063d20b1a51146103fc578063dcec33481461041c578063f2fde38b1461043157600080fd5b8063a4771aad146103a8578063d1de856c146103dc57600080fd5b8063715018a6146102cd5780637cbb46e3146102e25780638da5cb5b14610309578063a25ae5571461033457600080fd5b80632af8ded8116100fc5780634ab65d73116100e15780634ab65d7314610213578063529933df146102475780635c1bba381461027b57600080fd5b80632af8ded8146101dd5780634599c788146101fd57600080fd5b80622134cc1461012d578063093b3d901461017457806320e9fcd41461019657806325188104146101ca575b600080fd5b34801561013957600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561018057600080fd5b5061019461018f3660046114a1565b610451565b005b3480156101a257600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b6101946101d8366004611517565b6106f7565b3480156101e957600080fd5b506101946101f836600461156d565b610aa0565b34801561020957600080fd5b5061016160665481565b34801561021f57600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b34801561025357600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b34801561028757600080fd5b506065546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161016b565b3480156102d957600080fd5b50610194610cfd565b3480156102ee57600080fd5b506102f7600181565b60405160ff909116815260200161016b565b34801561031557600080fd5b5060335473ffffffffffffffffffffffffffffffffffffffff166102a8565b34801561034057600080fd5b5061038d61034f36600461158f565b604080518082019091526000808252602082015250600090815260676020908152604091829020825180840190935280548352600101549082015290565b6040805182518152602092830151928101929092520161016b565b3480156103b457600080fd5b506101617f000000000000000000000000000000000000000000000000000000000000000081565b3480156103e857600080fd5b506101616103f736600461158f565b610d8a565b34801561040857600080fd5b506101946104173660046115a8565b610ee7565b34801561042857600080fd5b50610161610fe4565b34801561043d57600080fd5b5061019461044c36600461156d565b611019565b60335473ffffffffffffffffffffffffffffffffffffffff1633146104d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b60665460009081526067602090815260409182902082518084019093528054808452600190910154918301919091528251146105bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605260248201527f4f75747075744f7261636c653a20546865206f757470757420726f6f7420746f60448201527f2064656c65746520646f6573206e6f74206d6174636820746865206c6174657360648201527f74206f75747075742070726f706f73616c2e0000000000000000000000000000608482015260a4016104ce565b8060200151826020015114610678576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605060248201527f4f75747075744f7261636c653a205468652074696d657374616d7020746f206460448201527f656c65746520646f6573206e6f74206d6174636820746865206c61746573742060648201527f6f75747075742070726f706f73616c2e00000000000000000000000000000000608482015260a4016104ce565b606654602082015182516040517f7320566fd5256cf8923648a5d9f560f1e92f1435a1bb32ddd1fe107f224ad35990600090a460668054600090815260676020526040812081815560010155546106f0907f00000000000000000000000000000000000000000000000000000000000000009061161d565b6066555050565b60655473ffffffffffffffffffffffffffffffffffffffff16331461079e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f75747075744f7261636c653a2063616c6c6572206973206e6f74207468652060448201527f73657175656e636572000000000000000000000000000000000000000000000060648201526084016104ce565b6107a6610fe4565b831461085a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604760248201527f4f75747075744f7261636c653a20426c6f636b206e756d626572206d7573742060448201527f626520657175616c20746f206e65787420657870656374656420626c6f636b2060648201527f6e756d6265722e00000000000000000000000000000000000000000000000000608482015260a4016104ce565b4261086484610d8a565b106108f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4f75747075744f7261636c653a2043616e6e6f7420617070656e64204c32206f60448201527f757470757420696e206675747572652e0000000000000000000000000000000060648201526084016104ce565b8361097e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4f75747075744f7261636c653a2043616e6e6f74207375626d697420656d707460448201527f79204c32206f75747075742e000000000000000000000000000000000000000060648201526084016104ce565b8115610a3a5781814014610a3a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604760248201527f4f75747075744f7261636c653a20426c6f636b6861736820646f6573206e6f7460448201527f206d61746368207468652068617368206174207468652065787065637465642060648201527f6865696768742e00000000000000000000000000000000000000000000000000608482015260a4016104ce565b6040805180820182528581524260208083018281526000888152606790925284822093518455516001909301929092556066869055915185929187917fd6703ded1701060d9ae1793db76d594790a4e775781225f79b5aa8a77987c0809190a450505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610b21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ce565b73ffffffffffffffffffffffffffffffffffffffff8116610bc4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4f75747075744f7261636c653a206e65772073657175656e636572206973207460448201527f6865207a65726f2061646472657373000000000000000000000000000000000060648201526084016104ce565b60335473ffffffffffffffffffffffffffffffffffffffff82811691161415610c6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f4f75747075744f7261636c653a2073657175656e6365722063616e6e6f74206260448201527f652073616d6520617320746865206f776e65720000000000000000000000000060648201526084016104ce565b60655460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f6ec88bae255aa7e73521c3beb17e9bc7940169e669440c5531733c0d2e91110d90600090a3606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610d7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ce565b610d886000611165565b565b60007f0000000000000000000000000000000000000000000000000000000000000000821015610e62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605660248201527f4f75747075744f7261636c653a20426c6f636b206e756d626572206d7573742060448201527f62652067726561746572207468616e206f7220657175616c20746f207468652060648201527f7374617274696e6720626c6f636b206e756d6265722e00000000000000000000608482015260a4016104ce565b7f0000000000000000000000000000000000000000000000000000000000000000610ead7f00000000000000000000000000000000000000000000000000000000000000008461161d565b610eb79190611634565b610ee1907f0000000000000000000000000000000000000000000000000000000000000000611671565b92915050565b60016000610ef4826111dc565b90508015610f2957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60408051808201825287815242602080830191825260008981526067909152929092209051815590516001909101556066859055610f65611367565b610f6e84610aa0565b610f7783611165565b8015610fdc57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff831681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006066546110149190611671565b905090565b60335473ffffffffffffffffffffffffffffffffffffffff16331461109a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ce565b73ffffffffffffffffffffffffffffffffffffffff811661113d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ce565b61114681611165565b50565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008054610100900460ff1615611293578160ff1660011480156111ff5750303b155b61128b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104ce565b506000919050565b60005460ff80841691161061132a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104ce565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166113fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104ce565b610d88600054610100900460ff16611498576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104ce565b610d8833611165565b6000604082840312156114b357600080fd5b6040516040810181811067ffffffffffffffff821117156114fd577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052823581526020928301359281019290925250919050565b6000806000806080858703121561152d57600080fd5b5050823594602084013594506040840135936060013592509050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461136257600080fd5b60006020828403121561157f57600080fd5b61158882611549565b9392505050565b6000602082840312156115a157600080fd5b5035919050565b600080600080608085870312156115be57600080fd5b84359350602085013592506115d560408601611549565b91506115e360608601611549565b905092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561162f5761162f6115ee565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561166c5761166c6115ee565b500290565b60008219821115611684576116846115ee565b50019056fea164736f6c634300080a000a496e697469616c697a61626c653a20636f6e747261637420697320616c726561496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069",
}
// L2OutputOracleABI is the input ABI used to generate the binding from.
......@@ -49,7 +49,7 @@ var L2OutputOracleABI = L2OutputOracleMetaData.ABI
var L2OutputOracleBin = L2OutputOracleMetaData.Bin
// DeployL2OutputOracle deploys a new Ethereum contract, binding an instance of L2OutputOracle to it.
func DeployL2OutputOracle(auth *bind.TransactOpts, backend bind.ContractBackend, _submissionInterval *big.Int, _genesisL2Output [32]byte, _historicalTotalBlocks *big.Int, _startingBlockNumber *big.Int, _startingTimestamp *big.Int, _l2BlockTime *big.Int, _sequencer common.Address) (common.Address, *types.Transaction, *L2OutputOracle, error) {
func DeployL2OutputOracle(auth *bind.TransactOpts, backend bind.ContractBackend, _submissionInterval *big.Int, _genesisL2Output [32]byte, _historicalTotalBlocks *big.Int, _startingBlockNumber *big.Int, _startingTimestamp *big.Int, _l2BlockTime *big.Int, _sequencer common.Address, _owner common.Address) (common.Address, *types.Transaction, *L2OutputOracle, error) {
parsed, err := L2OutputOracleMetaData.GetAbi()
if err != nil {
return common.Address{}, nil, nil, err
......@@ -58,7 +58,7 @@ func DeployL2OutputOracle(auth *bind.TransactOpts, backend bind.ContractBackend,
return common.Address{}, nil, nil, errors.New("GetABI returned nil")
}
address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(L2OutputOracleBin), backend, _submissionInterval, _genesisL2Output, _historicalTotalBlocks, _startingBlockNumber, _startingTimestamp, _l2BlockTime, _sequencer)
address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(L2OutputOracleBin), backend, _submissionInterval, _genesisL2Output, _historicalTotalBlocks, _startingBlockNumber, _startingTimestamp, _l2BlockTime, _sequencer, _owner)
if err != nil {
return common.Address{}, nil, nil, err
}
......@@ -269,6 +269,37 @@ func (_L2OutputOracle *L2OutputOracleCallerSession) L2BLOCKTIME() (*big.Int, err
return _L2OutputOracle.Contract.L2BLOCKTIME(&_L2OutputOracle.CallOpts)
}
// L2OUTPUTORACLEVERSION is a free data retrieval call binding the contract method 0x7cbb46e3.
//
// Solidity: function L2_OUTPUT_ORACLE_VERSION() view returns(uint8)
func (_L2OutputOracle *L2OutputOracleCaller) L2OUTPUTORACLEVERSION(opts *bind.CallOpts) (uint8, error) {
var out []interface{}
err := _L2OutputOracle.contract.Call(opts, &out, "L2_OUTPUT_ORACLE_VERSION")
if err != nil {
return *new(uint8), err
}
out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
return out0, err
}
// L2OUTPUTORACLEVERSION is a free data retrieval call binding the contract method 0x7cbb46e3.
//
// Solidity: function L2_OUTPUT_ORACLE_VERSION() view returns(uint8)
func (_L2OutputOracle *L2OutputOracleSession) L2OUTPUTORACLEVERSION() (uint8, error) {
return _L2OutputOracle.Contract.L2OUTPUTORACLEVERSION(&_L2OutputOracle.CallOpts)
}
// L2OUTPUTORACLEVERSION is a free data retrieval call binding the contract method 0x7cbb46e3.
//
// Solidity: function L2_OUTPUT_ORACLE_VERSION() view returns(uint8)
func (_L2OutputOracle *L2OutputOracleCallerSession) L2OUTPUTORACLEVERSION() (uint8, error) {
return _L2OutputOracle.Contract.L2OUTPUTORACLEVERSION(&_L2OutputOracle.CallOpts)
}
// STARTINGBLOCKNUMBER is a free data retrieval call binding the contract method 0x4ab65d73.
//
// Solidity: function STARTING_BLOCK_NUMBER() view returns(uint256)
......@@ -517,6 +548,37 @@ func (_L2OutputOracle *L2OutputOracleCallerSession) Owner() (common.Address, err
return _L2OutputOracle.Contract.Owner(&_L2OutputOracle.CallOpts)
}
// Sequencer is a free data retrieval call binding the contract method 0x5c1bba38.
//
// Solidity: function sequencer() view returns(address)
func (_L2OutputOracle *L2OutputOracleCaller) Sequencer(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _L2OutputOracle.contract.Call(opts, &out, "sequencer")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// Sequencer is a free data retrieval call binding the contract method 0x5c1bba38.
//
// Solidity: function sequencer() view returns(address)
func (_L2OutputOracle *L2OutputOracleSession) Sequencer() (common.Address, error) {
return _L2OutputOracle.Contract.Sequencer(&_L2OutputOracle.CallOpts)
}
// Sequencer is a free data retrieval call binding the contract method 0x5c1bba38.
//
// Solidity: function sequencer() view returns(address)
func (_L2OutputOracle *L2OutputOracleCallerSession) Sequencer() (common.Address, error) {
return _L2OutputOracle.Contract.Sequencer(&_L2OutputOracle.CallOpts)
}
// AppendL2Output is a paid mutator transaction binding the contract method 0x25188104.
//
// Solidity: function appendL2Output(bytes32 _l2Output, uint256 _l2BlockNumber, bytes32 _l1Blockhash, uint256 _l1BlockNumber) payable returns()
......@@ -538,6 +600,27 @@ func (_L2OutputOracle *L2OutputOracleTransactorSession) AppendL2Output(_l2Output
return _L2OutputOracle.Contract.AppendL2Output(&_L2OutputOracle.TransactOpts, _l2Output, _l2BlockNumber, _l1Blockhash, _l1BlockNumber)
}
// ChangeSequencer is a paid mutator transaction binding the contract method 0x2af8ded8.
//
// Solidity: function changeSequencer(address _newSequencer) returns()
func (_L2OutputOracle *L2OutputOracleTransactor) ChangeSequencer(opts *bind.TransactOpts, _newSequencer common.Address) (*types.Transaction, error) {
return _L2OutputOracle.contract.Transact(opts, "changeSequencer", _newSequencer)
}
// ChangeSequencer is a paid mutator transaction binding the contract method 0x2af8ded8.
//
// Solidity: function changeSequencer(address _newSequencer) returns()
func (_L2OutputOracle *L2OutputOracleSession) ChangeSequencer(_newSequencer common.Address) (*types.Transaction, error) {
return _L2OutputOracle.Contract.ChangeSequencer(&_L2OutputOracle.TransactOpts, _newSequencer)
}
// ChangeSequencer is a paid mutator transaction binding the contract method 0x2af8ded8.
//
// Solidity: function changeSequencer(address _newSequencer) returns()
func (_L2OutputOracle *L2OutputOracleTransactorSession) ChangeSequencer(_newSequencer common.Address) (*types.Transaction, error) {
return _L2OutputOracle.Contract.ChangeSequencer(&_L2OutputOracle.TransactOpts, _newSequencer)
}
// DeleteL2Output is a paid mutator transaction binding the contract method 0x093b3d90.
//
// Solidity: function deleteL2Output((bytes32,uint256) _proposal) returns()
......@@ -559,6 +642,27 @@ func (_L2OutputOracle *L2OutputOracleTransactorSession) DeleteL2Output(_proposal
return _L2OutputOracle.Contract.DeleteL2Output(&_L2OutputOracle.TransactOpts, _proposal)
}
// Initialize is a paid mutator transaction binding the contract method 0xd20b1a51.
//
// Solidity: function initialize(bytes32 _genesisL2Output, uint256 _startingBlockNumber, address _sequencer, address _owner) returns()
func (_L2OutputOracle *L2OutputOracleTransactor) Initialize(opts *bind.TransactOpts, _genesisL2Output [32]byte, _startingBlockNumber *big.Int, _sequencer common.Address, _owner common.Address) (*types.Transaction, error) {
return _L2OutputOracle.contract.Transact(opts, "initialize", _genesisL2Output, _startingBlockNumber, _sequencer, _owner)
}
// Initialize is a paid mutator transaction binding the contract method 0xd20b1a51.
//
// Solidity: function initialize(bytes32 _genesisL2Output, uint256 _startingBlockNumber, address _sequencer, address _owner) returns()
func (_L2OutputOracle *L2OutputOracleSession) Initialize(_genesisL2Output [32]byte, _startingBlockNumber *big.Int, _sequencer common.Address, _owner common.Address) (*types.Transaction, error) {
return _L2OutputOracle.Contract.Initialize(&_L2OutputOracle.TransactOpts, _genesisL2Output, _startingBlockNumber, _sequencer, _owner)
}
// Initialize is a paid mutator transaction binding the contract method 0xd20b1a51.
//
// Solidity: function initialize(bytes32 _genesisL2Output, uint256 _startingBlockNumber, address _sequencer, address _owner) returns()
func (_L2OutputOracle *L2OutputOracleTransactorSession) Initialize(_genesisL2Output [32]byte, _startingBlockNumber *big.Int, _sequencer common.Address, _owner common.Address) (*types.Transaction, error) {
return _L2OutputOracle.Contract.Initialize(&_L2OutputOracle.TransactOpts, _genesisL2Output, _startingBlockNumber, _sequencer, _owner)
}
// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6.
//
// Solidity: function renounceOwnership() returns()
......@@ -601,6 +705,140 @@ func (_L2OutputOracle *L2OutputOracleTransactorSession) TransferOwnership(newOwn
return _L2OutputOracle.Contract.TransferOwnership(&_L2OutputOracle.TransactOpts, newOwner)
}
// L2OutputOracleInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the L2OutputOracle contract.
type L2OutputOracleInitializedIterator struct {
Event *L2OutputOracleInitialized // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *L2OutputOracleInitializedIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(L2OutputOracleInitialized)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(L2OutputOracleInitialized)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *L2OutputOracleInitializedIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *L2OutputOracleInitializedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// L2OutputOracleInitialized represents a Initialized event raised by the L2OutputOracle contract.
type L2OutputOracleInitialized struct {
Version uint8
Raw types.Log // Blockchain specific contextual infos
}
// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498.
//
// Solidity: event Initialized(uint8 version)
func (_L2OutputOracle *L2OutputOracleFilterer) FilterInitialized(opts *bind.FilterOpts) (*L2OutputOracleInitializedIterator, error) {
logs, sub, err := _L2OutputOracle.contract.FilterLogs(opts, "Initialized")
if err != nil {
return nil, err
}
return &L2OutputOracleInitializedIterator{contract: _L2OutputOracle.contract, event: "Initialized", logs: logs, sub: sub}, nil
}
// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498.
//
// Solidity: event Initialized(uint8 version)
func (_L2OutputOracle *L2OutputOracleFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *L2OutputOracleInitialized) (event.Subscription, error) {
logs, sub, err := _L2OutputOracle.contract.WatchLogs(opts, "Initialized")
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(L2OutputOracleInitialized)
if err := _L2OutputOracle.contract.UnpackLog(event, "Initialized", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498.
//
// Solidity: event Initialized(uint8 version)
func (_L2OutputOracle *L2OutputOracleFilterer) ParseInitialized(log types.Log) (*L2OutputOracleInitialized, error) {
event := new(L2OutputOracleInitialized)
if err := _L2OutputOracle.contract.UnpackLog(event, "Initialized", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// L2OutputOracleL2OutputAppendedIterator is returned from FilterL2OutputAppended and is used to iterate over the raw logs and unpacked data for L2OutputAppended events raised by the L2OutputOracle contract.
type L2OutputOracleL2OutputAppendedIterator struct {
Event *L2OutputOracleL2OutputAppended // Event containing the contract specifics and raw log
......@@ -1077,3 +1315,156 @@ func (_L2OutputOracle *L2OutputOracleFilterer) ParseOwnershipTransferred(log typ
event.Raw = log
return event, nil
}
// L2OutputOracleSequencerChangedIterator is returned from FilterSequencerChanged and is used to iterate over the raw logs and unpacked data for SequencerChanged events raised by the L2OutputOracle contract.
type L2OutputOracleSequencerChangedIterator struct {
Event *L2OutputOracleSequencerChanged // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *L2OutputOracleSequencerChangedIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(L2OutputOracleSequencerChanged)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(L2OutputOracleSequencerChanged)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *L2OutputOracleSequencerChangedIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *L2OutputOracleSequencerChangedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// L2OutputOracleSequencerChanged represents a SequencerChanged event raised by the L2OutputOracle contract.
type L2OutputOracleSequencerChanged struct {
PreviousSequencer common.Address
NewSequencer common.Address
Raw types.Log // Blockchain specific contextual infos
}
// FilterSequencerChanged is a free log retrieval operation binding the contract event 0x6ec88bae255aa7e73521c3beb17e9bc7940169e669440c5531733c0d2e91110d.
//
// Solidity: event SequencerChanged(address indexed previousSequencer, address indexed newSequencer)
func (_L2OutputOracle *L2OutputOracleFilterer) FilterSequencerChanged(opts *bind.FilterOpts, previousSequencer []common.Address, newSequencer []common.Address) (*L2OutputOracleSequencerChangedIterator, error) {
var previousSequencerRule []interface{}
for _, previousSequencerItem := range previousSequencer {
previousSequencerRule = append(previousSequencerRule, previousSequencerItem)
}
var newSequencerRule []interface{}
for _, newSequencerItem := range newSequencer {
newSequencerRule = append(newSequencerRule, newSequencerItem)
}
logs, sub, err := _L2OutputOracle.contract.FilterLogs(opts, "SequencerChanged", previousSequencerRule, newSequencerRule)
if err != nil {
return nil, err
}
return &L2OutputOracleSequencerChangedIterator{contract: _L2OutputOracle.contract, event: "SequencerChanged", logs: logs, sub: sub}, nil
}
// WatchSequencerChanged is a free log subscription operation binding the contract event 0x6ec88bae255aa7e73521c3beb17e9bc7940169e669440c5531733c0d2e91110d.
//
// Solidity: event SequencerChanged(address indexed previousSequencer, address indexed newSequencer)
func (_L2OutputOracle *L2OutputOracleFilterer) WatchSequencerChanged(opts *bind.WatchOpts, sink chan<- *L2OutputOracleSequencerChanged, previousSequencer []common.Address, newSequencer []common.Address) (event.Subscription, error) {
var previousSequencerRule []interface{}
for _, previousSequencerItem := range previousSequencer {
previousSequencerRule = append(previousSequencerRule, previousSequencerItem)
}
var newSequencerRule []interface{}
for _, newSequencerItem := range newSequencer {
newSequencerRule = append(newSequencerRule, newSequencerItem)
}
logs, sub, err := _L2OutputOracle.contract.WatchLogs(opts, "SequencerChanged", previousSequencerRule, newSequencerRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(L2OutputOracleSequencerChanged)
if err := _L2OutputOracle.contract.UnpackLog(event, "SequencerChanged", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseSequencerChanged is a log parse operation binding the contract event 0x6ec88bae255aa7e73521c3beb17e9bc7940169e669440c5531733c0d2e91110d.
//
// Solidity: event SequencerChanged(address indexed previousSequencer, address indexed newSequencer)
func (_L2OutputOracle *L2OutputOracleFilterer) ParseSequencerChanged(log types.Log) (*L2OutputOracleSequencerChanged, error) {
event := new(L2OutputOracleSequencerChanged)
if err := _L2OutputOracle.contract.UnpackLog(event, "SequencerChanged", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
......@@ -402,7 +402,7 @@ func (cfg SystemConfig) start() (*System, error) {
// Deploy Deposit Contract
deployerPrivKey, err := sys.wallet.PrivateKey(accounts.Account{
URL: accounts.URL{
Path: sys.cfg.DeployerHDPath,
Path: cfg.DeployerHDPath,
},
})
if err != nil {
......@@ -425,6 +425,7 @@ func (cfg SystemConfig) start() (*System, error) {
sys.cfg.L2OOCfg.L2StartingTimeStamp,
sys.cfg.L2OOCfg.L2BlockTime,
l2OutputSubmitterAddr,
crypto.PubkeyToAddress(deployerPrivKey.PublicKey),
)
sys.cfg.DepositCFG.L2Oracle = sys.L2OOContractAddr
if err != nil {
......
......@@ -57,6 +57,7 @@ const (
l2OutputHDPath = "m/44'/60'/0'/0/3"
bssHDPath = "m/44'/60'/0'/0/4"
p2pSignerHDPath = "m/44'/60'/0'/0/5"
deployerHDPath = "m/44'/60'/0'/0/6"
)
var (
......@@ -81,19 +82,21 @@ func defaultSystemConfig(t *testing.T) SystemConfig {
transactorHDPath: 10000000,
l2OutputHDPath: 10000000,
bssHDPath: 10000000,
deployerHDPath: 10000000,
},
DepositCFG: DepositContractConfig{
FinalizationPeriod: big.NewInt(60 * 60 * 24),
},
L2OOCfg: L2OOContractConfig{
// L2 Start time is set based off of the L2 Genesis time
SubmissionFrequency: big.NewInt(2),
SubmissionFrequency: big.NewInt(4),
L2BlockTime: big.NewInt(2),
HistoricalTotalBlocks: big.NewInt(0),
},
L2OutputHDPath: l2OutputHDPath,
BatchSubmitterHDPath: bssHDPath,
P2PSignerHDPath: p2pSignerHDPath,
DeployerHDPath: l2OutputHDPath,
DeployerHDPath: deployerHDPath,
CliqueSignerDerivationPath: cliqueSignerHDPath,
L1InfoPredeployAddress: predeploys.L1BlockAddr,
L1BlockTime: 2,
......@@ -789,7 +792,7 @@ func TestWithdrawals(t *testing.T) {
require.Nil(t, err)
// Wait for finalization and then create the Finalized Withdrawal Transaction
ctx, cancel = context.WithTimeout(context.Background(), 10*time.Duration(cfg.L1BlockTime)*time.Second)
ctx, cancel = context.WithTimeout(context.Background(), 20*time.Duration(cfg.L1BlockTime)*time.Second)
defer cancel()
blockNumber, err := withdrawals.WaitForFinalizationPeriod(ctx, l1Client, sys.DepositContractAddr, receipt.BlockNumber)
require.Nil(t, err)
......
......@@ -33,6 +33,7 @@ L1_URL="http://localhost:8545"
L2_URL="http://localhost:9545"
CONTRACTS_BEDROCK=./packages/contracts-bedrock
NETWORK=devnetL1
# Helper method that waits for a given URL to be up. Can't use
# cURL's built-in retry logic because connection reset errors
......@@ -46,7 +47,7 @@ function wait_up {
sleep 0.25
((i=i+1))
if [ "$i" -eq 120 ]; then
if [ "$i" -eq 200 ]; then
echo " Timeout!" >&2
exit 0
fi
......@@ -54,15 +55,24 @@ function wait_up {
echo "Done!"
}
mkdir -p ./.devnet
if [ ! -f ./.devnet/rollup.json ]; then
GENESIS_TIMESTAMP=$(date +%s | xargs printf "0x%x")
else
GENESIS_TIMESTAMP=$(jq '.genesis.l2_time' < .devnet/rollup.json)
fi
# Regenerate the L1 genesis file if necessary. The existence of the genesis
# file is used to determine if we need to recreate the devnet's state folder.
if [ ! -f ./.devnet/genesis-l1.json ]; then
echo "Regenerating L1 genesis."
mkdir -p ./.devnet
GENESIS_TIMESTAMP=$(date +%s | xargs printf "0x%x")
jq ". | .timestamp = \"$GENESIS_TIMESTAMP\" " < ./ops-bedrock/genesis-l1.json > ./.devnet/genesis-l1.json
else
GENESIS_TIMESTAMP=$(jq -r '.timestamp' < ./.devnet/genesis-l1.json)
(
cd $CONTRACTS_BEDROCK
L2OO_STARTING_BLOCK_TIMESTAMP=$GENESIS_TIMESTAMP npx hardhat genesis-l1 \
--outfile genesis-l1.json
mv genesis-l1.json ../../.devnet/genesis-l1.json
)
fi
# Bring up L1.
......@@ -75,43 +85,27 @@ fi
)
# Deploy contracts using Hardhat.
if [ ! -f $CONTRACTS_BEDROCK/deployments/devnetL1/OptimismPortal.json ]; then
echo "Deploying contracts."
if [ ! -d $CONTRACTS_BEDROCK/deployments/$NETWORK ]; then
(
echo "Deploying contracts."
cd $CONTRACTS_BEDROCK
L2OO_STARTING_BLOCK_TIMESTAMP=$GENESIS_TIMESTAMP yarn hardhat --network devnetL1 deploy
L2OO_STARTING_BLOCK_TIMESTAMP=$GENESIS_TIMESTAMP yarn hardhat --network $NETWORK deploy
)
else
echo "Contracts already deployed, skipping."
fi
function get_deployed_bytecode() {
echo $(jq -r .deployedBytecode $CONTRACTS_BEDROCK/artifacts/contracts/$1)
}
# Pull out the necessary bytecode/addresses from the artifacts/deployments.
L2_TO_L1_MESSAGE_PASSER_BYTECODE=$(get_deployed_bytecode L2/L2ToL1MessagePasser.sol/L2ToL1MessagePasser.json)
L2_CROSS_DOMAIN_MESSENGER_BYTECODE=$(get_deployed_bytecode L2/L2CrossDomainMessenger.sol/L2CrossDomainMessenger.json)
OPTIMISM_MINTABLE_TOKEN_FACTORY_BYTECODE=$(get_deployed_bytecode universal/OptimismMintableTokenFactory.sol/OptimismMintableTokenFactory.json)
L2_STANDARD_BRIDGE_BYTECODE=$(get_deployed_bytecode L2/L2StandardBridge.sol/L2StandardBridge.json)
L1_BLOCK_INFO_BYTECODE=$(get_deployed_bytecode L2/L1Block.sol/L1Block.json)
DEPOSIT_CONTRACT_ADDRESS=$(jq -r .address < $CONTRACTS_BEDROCK/deployments/devnetL1/OptimismPortal.json)
L2OO_ADDRESS=$(jq -r .address < $CONTRACTS_BEDROCK/deployments/devnetL1/L2OutputOracle.json)
# Replace values in the L2 genesis file. It doesn't matter if this gets run every time,
# since the replaced values will be the same.
jq ". | .alloc.\"4200000000000000000000000000000000000015\".code = \"$L1_BLOCK_INFO_BYTECODE\"" < ./ops-bedrock/genesis-l2.json | \
jq ". | .alloc.\"4200000000000000000000000000000000000015\".balance = \"0x0\"" | \
jq ". | .alloc.\"4200000000000000000000000000000000000000\".code = \"$L2_TO_L1_MESSAGE_PASSER_BYTECODE\"" | \
jq ". | .alloc.\"4200000000000000000000000000000000000000\".balance = \"0x0\"" | \
jq ". | .alloc.\"4200000000000000000000000000000000000007\".code = \"$L2_CROSS_DOMAIN_MESSENGER_BYTECODE\"" | \
jq ". | .alloc.\"4200000000000000000000000000000000000007\".balance = \"0x0\"" | \
jq ". | .alloc.\"4200000000000000000000000000000000000012\".code = \"$OPTIMISM_MINTABLE_TOKEN_FACTORY_BYTECODE\"" | \
jq ". | .alloc.\"4200000000000000000000000000000000000012\".balance = \"0x0\"" | \
jq ". | .alloc.\"4200000000000000000000000000000000000010\".code = \"$L2_STANDARD_BRIDGE_BYTECODE\"" | \
jq ". | .alloc.\"4200000000000000000000000000000000000010\".balance = \"0x0\"" | \
jq ". | .timestamp = \"$GENESIS_TIMESTAMP\" " > ./.devnet/genesis-l2.json
if [ ! -f ./.devnet/genesis-l2.json ]; then
(
echo "Creating L2 genesis file."
cd $CONTRACTS_BEDROCK
L2OO_STARTING_BLOCK_TIMESTAMP=$GENESIS_TIMESTAMP npx hardhat --network $NETWORK genesis-l2
mv genesis.json ../../.devnet/genesis-l2.json
echo "Created L2 genesis."
)
else
echo "L2 genesis already exists."
fi
# Bring up L2.
(
......@@ -122,40 +116,19 @@ jq ". | .alloc.\"4200000000000000000000000000000000000015\".code = \"$L1_BLOCK_I
)
# Start putting together the rollup config.
echo "Building rollup config..."
# Grab the L1 genesis. We can use cURL here to retry.
L1_GENESIS=$(curl \
--silent \
--fail \
--retry 10 \
--retry-delay 2 \
--retry-connrefused \
-X POST \
-H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x0", false],"id":1}' \
$L1_URL)
# Grab the L2 genesis. We can use cURL here to retry.
L2_GENESIS=$(curl \
--silent \
--fail \
--retry 10 \
--retry-delay 2 \
--retry-connrefused \
-X POST \
-H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x0", false],"id":1}' \
$L2_URL)
# Generate the rollup config.
jq ". | .genesis.l1.hash = \"$(echo $L1_GENESIS | jq -r '.result.hash')\"" < ./ops-bedrock/rollup.json | \
jq ". | .genesis.l2.hash = \"$(echo $L2_GENESIS | jq -r '.result.hash')\"" | \
jq ". | .genesis.l2_time = $(echo $L2_GENESIS | jq -r '.result.timestamp' | xargs printf "%d")" | \
jq ". | .deposit_contract_address = \"$DEPOSIT_CONTRACT_ADDRESS\"" > ./.devnet/rollup.json
SEQUENCER_GENESIS_HASH="$(echo $L2_GENESIS | jq -r '.result.hash')"
if [ ! -f ./.devnet/rollup.json ]; then
(
echo "Building rollup config..."
cd $CONTRACTS_BEDROCK
L2OO_STARTING_BLOCK_TIMESTAMP=$GENESIS_TIMESTAMP npx hardhat rollup-config --network $NETWORK
mv rollup.json ../../.devnet/rollup.json
)
else
echo "Rollup config already exists"
fi
L2OO_ADDRESS=$(jq -r .address < $CONTRACTS_BEDROCK/deployments/$NETWORK/L2OutputOracleProxy.json)
SEQUENCER_GENESIS_HASH="$(jq -r '.l2.hash' < .devnet/rollup.json)"
SEQUENCER_BATCH_INBOX_ADDRESS="$(cat ./ops-bedrock/rollup.json | jq -r '.batch_inbox_address')"
# Bring up everything else.
......
{
"config": {
"chainId": 900,
"homesteadBlock": 0,
"eip150Block": 0,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"berlinBlock": 0,
"londonBlock": 0,
"clique": {
"period": 15,
"epoch": 30000
}
},
"nonce": "0x0",
"timestamp": "",
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000ca062b0fd91172d89bcd4bb084ac4e21972cc4670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0xE4E1C0",
"difficulty": "0x1",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": {
"0000000000000000000000000000000000000000": {
"balance": "0x1"
},
"0000000000000000000000000000000000000001": {
"balance": "0x1"
},
"0000000000000000000000000000000000000002": {
"balance": "0x1"
},
"0000000000000000000000000000000000000003": {
"balance": "0x1"
},
"0000000000000000000000000000000000000004": {
"balance": "0x1"
},
"0000000000000000000000000000000000000005": {
"balance": "0x1"
},
"0000000000000000000000000000000000000006": {
"balance": "0x1"
},
"0000000000000000000000000000000000000007": {
"balance": "0x1"
},
"0000000000000000000000000000000000000008": {
"balance": "0x1"
},
"0000000000000000000000000000000000000009": {
"balance": "0x1"
},
"000000000000000000000000000000000000000a": {
"balance": "0x1"
},
"000000000000000000000000000000000000000b": {
"balance": "0x1"
},
"000000000000000000000000000000000000000c": {
"balance": "0x1"
},
"000000000000000000000000000000000000000d": {
"balance": "0x1"
},
"000000000000000000000000000000000000000e": {
"balance": "0x1"
},
"000000000000000000000000000000000000000f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000010": {
"balance": "0x1"
},
"0000000000000000000000000000000000000011": {
"balance": "0x1"
},
"0000000000000000000000000000000000000012": {
"balance": "0x1"
},
"0000000000000000000000000000000000000013": {
"balance": "0x1"
},
"0000000000000000000000000000000000000014": {
"balance": "0x1"
},
"0000000000000000000000000000000000000015": {
"balance": "0x1"
},
"0000000000000000000000000000000000000016": {
"balance": "0x1"
},
"0000000000000000000000000000000000000017": {
"balance": "0x1"
},
"0000000000000000000000000000000000000018": {
"balance": "0x1"
},
"0000000000000000000000000000000000000019": {
"balance": "0x1"
},
"000000000000000000000000000000000000001a": {
"balance": "0x1"
},
"000000000000000000000000000000000000001b": {
"balance": "0x1"
},
"000000000000000000000000000000000000001c": {
"balance": "0x1"
},
"000000000000000000000000000000000000001d": {
"balance": "0x1"
},
"000000000000000000000000000000000000001e": {
"balance": "0x1"
},
"000000000000000000000000000000000000001f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000020": {
"balance": "0x1"
},
"0000000000000000000000000000000000000021": {
"balance": "0x1"
},
"0000000000000000000000000000000000000022": {
"balance": "0x1"
},
"0000000000000000000000000000000000000023": {
"balance": "0x1"
},
"0000000000000000000000000000000000000024": {
"balance": "0x1"
},
"0000000000000000000000000000000000000025": {
"balance": "0x1"
},
"0000000000000000000000000000000000000026": {
"balance": "0x1"
},
"0000000000000000000000000000000000000027": {
"balance": "0x1"
},
"0000000000000000000000000000000000000028": {
"balance": "0x1"
},
"0000000000000000000000000000000000000029": {
"balance": "0x1"
},
"000000000000000000000000000000000000002a": {
"balance": "0x1"
},
"000000000000000000000000000000000000002b": {
"balance": "0x1"
},
"000000000000000000000000000000000000002c": {
"balance": "0x1"
},
"000000000000000000000000000000000000002d": {
"balance": "0x1"
},
"000000000000000000000000000000000000002e": {
"balance": "0x1"
},
"000000000000000000000000000000000000002f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000030": {
"balance": "0x1"
},
"0000000000000000000000000000000000000031": {
"balance": "0x1"
},
"0000000000000000000000000000000000000032": {
"balance": "0x1"
},
"0000000000000000000000000000000000000033": {
"balance": "0x1"
},
"0000000000000000000000000000000000000034": {
"balance": "0x1"
},
"0000000000000000000000000000000000000035": {
"balance": "0x1"
},
"0000000000000000000000000000000000000036": {
"balance": "0x1"
},
"0000000000000000000000000000000000000037": {
"balance": "0x1"
},
"0000000000000000000000000000000000000038": {
"balance": "0x1"
},
"0000000000000000000000000000000000000039": {
"balance": "0x1"
},
"000000000000000000000000000000000000003a": {
"balance": "0x1"
},
"000000000000000000000000000000000000003b": {
"balance": "0x1"
},
"000000000000000000000000000000000000003c": {
"balance": "0x1"
},
"000000000000000000000000000000000000003d": {
"balance": "0x1"
},
"000000000000000000000000000000000000003e": {
"balance": "0x1"
},
"000000000000000000000000000000000000003f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000040": {
"balance": "0x1"
},
"0000000000000000000000000000000000000041": {
"balance": "0x1"
},
"0000000000000000000000000000000000000042": {
"balance": "0x1"
},
"0000000000000000000000000000000000000043": {
"balance": "0x1"
},
"0000000000000000000000000000000000000044": {
"balance": "0x1"
},
"0000000000000000000000000000000000000045": {
"balance": "0x1"
},
"0000000000000000000000000000000000000046": {
"balance": "0x1"
},
"0000000000000000000000000000000000000047": {
"balance": "0x1"
},
"0000000000000000000000000000000000000048": {
"balance": "0x1"
},
"0000000000000000000000000000000000000049": {
"balance": "0x1"
},
"000000000000000000000000000000000000004a": {
"balance": "0x1"
},
"000000000000000000000000000000000000004b": {
"balance": "0x1"
},
"000000000000000000000000000000000000004c": {
"balance": "0x1"
},
"000000000000000000000000000000000000004d": {
"balance": "0x1"
},
"000000000000000000000000000000000000004e": {
"balance": "0x1"
},
"000000000000000000000000000000000000004f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000050": {
"balance": "0x1"
},
"0000000000000000000000000000000000000051": {
"balance": "0x1"
},
"0000000000000000000000000000000000000052": {
"balance": "0x1"
},
"0000000000000000000000000000000000000053": {
"balance": "0x1"
},
"0000000000000000000000000000000000000054": {
"balance": "0x1"
},
"0000000000000000000000000000000000000055": {
"balance": "0x1"
},
"0000000000000000000000000000000000000056": {
"balance": "0x1"
},
"0000000000000000000000000000000000000057": {
"balance": "0x1"
},
"0000000000000000000000000000000000000058": {
"balance": "0x1"
},
"0000000000000000000000000000000000000059": {
"balance": "0x1"
},
"000000000000000000000000000000000000005a": {
"balance": "0x1"
},
"000000000000000000000000000000000000005b": {
"balance": "0x1"
},
"000000000000000000000000000000000000005c": {
"balance": "0x1"
},
"000000000000000000000000000000000000005d": {
"balance": "0x1"
},
"000000000000000000000000000000000000005e": {
"balance": "0x1"
},
"000000000000000000000000000000000000005f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000060": {
"balance": "0x1"
},
"0000000000000000000000000000000000000061": {
"balance": "0x1"
},
"0000000000000000000000000000000000000062": {
"balance": "0x1"
},
"0000000000000000000000000000000000000063": {
"balance": "0x1"
},
"0000000000000000000000000000000000000064": {
"balance": "0x1"
},
"0000000000000000000000000000000000000065": {
"balance": "0x1"
},
"0000000000000000000000000000000000000066": {
"balance": "0x1"
},
"0000000000000000000000000000000000000067": {
"balance": "0x1"
},
"0000000000000000000000000000000000000068": {
"balance": "0x1"
},
"0000000000000000000000000000000000000069": {
"balance": "0x1"
},
"000000000000000000000000000000000000006a": {
"balance": "0x1"
},
"000000000000000000000000000000000000006b": {
"balance": "0x1"
},
"000000000000000000000000000000000000006c": {
"balance": "0x1"
},
"000000000000000000000000000000000000006d": {
"balance": "0x1"
},
"000000000000000000000000000000000000006e": {
"balance": "0x1"
},
"000000000000000000000000000000000000006f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000070": {
"balance": "0x1"
},
"0000000000000000000000000000000000000071": {
"balance": "0x1"
},
"0000000000000000000000000000000000000072": {
"balance": "0x1"
},
"0000000000000000000000000000000000000073": {
"balance": "0x1"
},
"0000000000000000000000000000000000000074": {
"balance": "0x1"
},
"0000000000000000000000000000000000000075": {
"balance": "0x1"
},
"0000000000000000000000000000000000000076": {
"balance": "0x1"
},
"0000000000000000000000000000000000000077": {
"balance": "0x1"
},
"0000000000000000000000000000000000000078": {
"balance": "0x1"
},
"0000000000000000000000000000000000000079": {
"balance": "0x1"
},
"000000000000000000000000000000000000007a": {
"balance": "0x1"
},
"000000000000000000000000000000000000007b": {
"balance": "0x1"
},
"000000000000000000000000000000000000007c": {
"balance": "0x1"
},
"000000000000000000000000000000000000007d": {
"balance": "0x1"
},
"000000000000000000000000000000000000007e": {
"balance": "0x1"
},
"000000000000000000000000000000000000007f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000080": {
"balance": "0x1"
},
"0000000000000000000000000000000000000081": {
"balance": "0x1"
},
"0000000000000000000000000000000000000082": {
"balance": "0x1"
},
"0000000000000000000000000000000000000083": {
"balance": "0x1"
},
"0000000000000000000000000000000000000084": {
"balance": "0x1"
},
"0000000000000000000000000000000000000085": {
"balance": "0x1"
},
"0000000000000000000000000000000000000086": {
"balance": "0x1"
},
"0000000000000000000000000000000000000087": {
"balance": "0x1"
},
"0000000000000000000000000000000000000088": {
"balance": "0x1"
},
"0000000000000000000000000000000000000089": {
"balance": "0x1"
},
"000000000000000000000000000000000000008a": {
"balance": "0x1"
},
"000000000000000000000000000000000000008b": {
"balance": "0x1"
},
"000000000000000000000000000000000000008c": {
"balance": "0x1"
},
"000000000000000000000000000000000000008d": {
"balance": "0x1"
},
"000000000000000000000000000000000000008e": {
"balance": "0x1"
},
"000000000000000000000000000000000000008f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000090": {
"balance": "0x1"
},
"0000000000000000000000000000000000000091": {
"balance": "0x1"
},
"0000000000000000000000000000000000000092": {
"balance": "0x1"
},
"0000000000000000000000000000000000000093": {
"balance": "0x1"
},
"0000000000000000000000000000000000000094": {
"balance": "0x1"
},
"0000000000000000000000000000000000000095": {
"balance": "0x1"
},
"0000000000000000000000000000000000000096": {
"balance": "0x1"
},
"0000000000000000000000000000000000000097": {
"balance": "0x1"
},
"0000000000000000000000000000000000000098": {
"balance": "0x1"
},
"0000000000000000000000000000000000000099": {
"balance": "0x1"
},
"000000000000000000000000000000000000009a": {
"balance": "0x1"
},
"000000000000000000000000000000000000009b": {
"balance": "0x1"
},
"000000000000000000000000000000000000009c": {
"balance": "0x1"
},
"000000000000000000000000000000000000009d": {
"balance": "0x1"
},
"000000000000000000000000000000000000009e": {
"balance": "0x1"
},
"000000000000000000000000000000000000009f": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a0": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a1": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a2": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a3": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a4": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a5": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a6": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a7": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a8": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a9": {
"balance": "0x1"
},
"00000000000000000000000000000000000000aa": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ab": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ac": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ad": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ae": {
"balance": "0x1"
},
"00000000000000000000000000000000000000af": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b0": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b1": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b2": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b3": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b4": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b5": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b6": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b7": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b8": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b9": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ba": {
"balance": "0x1"
},
"00000000000000000000000000000000000000bb": {
"balance": "0x1"
},
"00000000000000000000000000000000000000bc": {
"balance": "0x1"
},
"00000000000000000000000000000000000000bd": {
"balance": "0x1"
},
"00000000000000000000000000000000000000be": {
"balance": "0x1"
},
"00000000000000000000000000000000000000bf": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c0": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c1": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c2": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c3": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c4": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c5": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c6": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c7": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c8": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c9": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ca": {
"balance": "0x1"
},
"00000000000000000000000000000000000000cb": {
"balance": "0x1"
},
"00000000000000000000000000000000000000cc": {
"balance": "0x1"
},
"00000000000000000000000000000000000000cd": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ce": {
"balance": "0x1"
},
"00000000000000000000000000000000000000cf": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d0": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d1": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d2": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d3": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d4": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d5": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d6": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d7": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d8": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d9": {
"balance": "0x1"
},
"00000000000000000000000000000000000000da": {
"balance": "0x1"
},
"00000000000000000000000000000000000000db": {
"balance": "0x1"
},
"00000000000000000000000000000000000000dc": {
"balance": "0x1"
},
"00000000000000000000000000000000000000dd": {
"balance": "0x1"
},
"00000000000000000000000000000000000000de": {
"balance": "0x1"
},
"00000000000000000000000000000000000000df": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e0": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e1": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e2": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e3": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e4": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e5": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e6": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e7": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e8": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e9": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ea": {
"balance": "0x1"
},
"00000000000000000000000000000000000000eb": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ec": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ed": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ee": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ef": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f0": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f1": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f2": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f3": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f4": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f5": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f6": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f7": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f8": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f9": {
"balance": "0x1"
},
"00000000000000000000000000000000000000fa": {
"balance": "0x1"
},
"00000000000000000000000000000000000000fb": {
"balance": "0x1"
},
"00000000000000000000000000000000000000fc": {
"balance": "0x1"
},
"00000000000000000000000000000000000000fd": {
"balance": "0x1"
},
"00000000000000000000000000000000000000fe": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ff": {
"balance": "0x1"
},
"de3829a23df1479438622a08a116e8eb3f620bb5": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
},
"3C44CdDdB6a900fa2b585dd299e03d12FA4293BC": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
},
"f39fd6e51aad88f6f4ce6ab8827279cfffb92266": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
},
"70997970C51812dc3A010C7d01b50e0d17dc79C8": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
}
},
"number": "0x0",
"gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"baseFeePerGas": null
}
{
"config": {
"chainId": 901,
"homesteadBlock": 0,
"eip150Block": 0,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"berlinBlock": 0,
"londonBlock": 0,
"mergeForkBlock": 0,
"terminalTotalDifficulty": 0
},
"nonce": "0x1234",
"timestamp": "",
"extraData": "0x",
"gasLimit": "0xE4E1C0",
"difficulty": "0x1",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": {
"0000000000000000000000000000000000000000": {
"balance": "0x1"
},
"0000000000000000000000000000000000000001": {
"balance": "0x1"
},
"0000000000000000000000000000000000000002": {
"balance": "0x1"
},
"0000000000000000000000000000000000000003": {
"balance": "0x1"
},
"0000000000000000000000000000000000000004": {
"balance": "0x1"
},
"0000000000000000000000000000000000000005": {
"balance": "0x1"
},
"0000000000000000000000000000000000000006": {
"balance": "0x1"
},
"0000000000000000000000000000000000000007": {
"balance": "0x1"
},
"0000000000000000000000000000000000000008": {
"balance": "0x1"
},
"0000000000000000000000000000000000000009": {
"balance": "0x1"
},
"000000000000000000000000000000000000000a": {
"balance": "0x1"
},
"000000000000000000000000000000000000000b": {
"balance": "0x1"
},
"000000000000000000000000000000000000000c": {
"balance": "0x1"
},
"000000000000000000000000000000000000000d": {
"balance": "0x1"
},
"000000000000000000000000000000000000000e": {
"balance": "0x1"
},
"000000000000000000000000000000000000000f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000010": {
"balance": "0x1"
},
"0000000000000000000000000000000000000011": {
"balance": "0x1"
},
"0000000000000000000000000000000000000012": {
"balance": "0x1"
},
"0000000000000000000000000000000000000013": {
"balance": "0x1"
},
"0000000000000000000000000000000000000014": {
"balance": "0x1"
},
"0000000000000000000000000000000000000015": {
"balance": "0x1"
},
"0000000000000000000000000000000000000016": {
"balance": "0x1"
},
"0000000000000000000000000000000000000017": {
"balance": "0x1"
},
"0000000000000000000000000000000000000018": {
"balance": "0x1"
},
"0000000000000000000000000000000000000019": {
"balance": "0x1"
},
"000000000000000000000000000000000000001a": {
"balance": "0x1"
},
"000000000000000000000000000000000000001b": {
"balance": "0x1"
},
"000000000000000000000000000000000000001c": {
"balance": "0x1"
},
"000000000000000000000000000000000000001d": {
"balance": "0x1"
},
"000000000000000000000000000000000000001e": {
"balance": "0x1"
},
"000000000000000000000000000000000000001f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000020": {
"balance": "0x1"
},
"0000000000000000000000000000000000000021": {
"balance": "0x1"
},
"0000000000000000000000000000000000000022": {
"balance": "0x1"
},
"0000000000000000000000000000000000000023": {
"balance": "0x1"
},
"0000000000000000000000000000000000000024": {
"balance": "0x1"
},
"0000000000000000000000000000000000000025": {
"balance": "0x1"
},
"0000000000000000000000000000000000000026": {
"balance": "0x1"
},
"0000000000000000000000000000000000000027": {
"balance": "0x1"
},
"0000000000000000000000000000000000000028": {
"balance": "0x1"
},
"0000000000000000000000000000000000000029": {
"balance": "0x1"
},
"000000000000000000000000000000000000002a": {
"balance": "0x1"
},
"000000000000000000000000000000000000002b": {
"balance": "0x1"
},
"000000000000000000000000000000000000002c": {
"balance": "0x1"
},
"000000000000000000000000000000000000002d": {
"balance": "0x1"
},
"000000000000000000000000000000000000002e": {
"balance": "0x1"
},
"000000000000000000000000000000000000002f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000030": {
"balance": "0x1"
},
"0000000000000000000000000000000000000031": {
"balance": "0x1"
},
"0000000000000000000000000000000000000032": {
"balance": "0x1"
},
"0000000000000000000000000000000000000033": {
"balance": "0x1"
},
"0000000000000000000000000000000000000034": {
"balance": "0x1"
},
"0000000000000000000000000000000000000035": {
"balance": "0x1"
},
"0000000000000000000000000000000000000036": {
"balance": "0x1"
},
"0000000000000000000000000000000000000037": {
"balance": "0x1"
},
"0000000000000000000000000000000000000038": {
"balance": "0x1"
},
"0000000000000000000000000000000000000039": {
"balance": "0x1"
},
"000000000000000000000000000000000000003a": {
"balance": "0x1"
},
"000000000000000000000000000000000000003b": {
"balance": "0x1"
},
"000000000000000000000000000000000000003c": {
"balance": "0x1"
},
"000000000000000000000000000000000000003d": {
"balance": "0x1"
},
"000000000000000000000000000000000000003e": {
"balance": "0x1"
},
"000000000000000000000000000000000000003f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000040": {
"balance": "0x1"
},
"0000000000000000000000000000000000000041": {
"balance": "0x1"
},
"0000000000000000000000000000000000000042": {
"balance": "0x1"
},
"0000000000000000000000000000000000000043": {
"balance": "0x1"
},
"0000000000000000000000000000000000000044": {
"balance": "0x1"
},
"0000000000000000000000000000000000000045": {
"balance": "0x1"
},
"0000000000000000000000000000000000000046": {
"balance": "0x1"
},
"0000000000000000000000000000000000000047": {
"balance": "0x1"
},
"0000000000000000000000000000000000000048": {
"balance": "0x1"
},
"0000000000000000000000000000000000000049": {
"balance": "0x1"
},
"000000000000000000000000000000000000004a": {
"balance": "0x1"
},
"000000000000000000000000000000000000004b": {
"balance": "0x1"
},
"000000000000000000000000000000000000004c": {
"balance": "0x1"
},
"000000000000000000000000000000000000004d": {
"balance": "0x1"
},
"000000000000000000000000000000000000004e": {
"balance": "0x1"
},
"000000000000000000000000000000000000004f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000050": {
"balance": "0x1"
},
"0000000000000000000000000000000000000051": {
"balance": "0x1"
},
"0000000000000000000000000000000000000052": {
"balance": "0x1"
},
"0000000000000000000000000000000000000053": {
"balance": "0x1"
},
"0000000000000000000000000000000000000054": {
"balance": "0x1"
},
"0000000000000000000000000000000000000055": {
"balance": "0x1"
},
"0000000000000000000000000000000000000056": {
"balance": "0x1"
},
"0000000000000000000000000000000000000057": {
"balance": "0x1"
},
"0000000000000000000000000000000000000058": {
"balance": "0x1"
},
"0000000000000000000000000000000000000059": {
"balance": "0x1"
},
"000000000000000000000000000000000000005a": {
"balance": "0x1"
},
"000000000000000000000000000000000000005b": {
"balance": "0x1"
},
"000000000000000000000000000000000000005c": {
"balance": "0x1"
},
"000000000000000000000000000000000000005d": {
"balance": "0x1"
},
"000000000000000000000000000000000000005e": {
"balance": "0x1"
},
"000000000000000000000000000000000000005f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000060": {
"balance": "0x1"
},
"0000000000000000000000000000000000000061": {
"balance": "0x1"
},
"0000000000000000000000000000000000000062": {
"balance": "0x1"
},
"0000000000000000000000000000000000000063": {
"balance": "0x1"
},
"0000000000000000000000000000000000000064": {
"balance": "0x1"
},
"0000000000000000000000000000000000000065": {
"balance": "0x1"
},
"0000000000000000000000000000000000000066": {
"balance": "0x1"
},
"0000000000000000000000000000000000000067": {
"balance": "0x1"
},
"0000000000000000000000000000000000000068": {
"balance": "0x1"
},
"0000000000000000000000000000000000000069": {
"balance": "0x1"
},
"000000000000000000000000000000000000006a": {
"balance": "0x1"
},
"000000000000000000000000000000000000006b": {
"balance": "0x1"
},
"000000000000000000000000000000000000006c": {
"balance": "0x1"
},
"000000000000000000000000000000000000006d": {
"balance": "0x1"
},
"000000000000000000000000000000000000006e": {
"balance": "0x1"
},
"000000000000000000000000000000000000006f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000070": {
"balance": "0x1"
},
"0000000000000000000000000000000000000071": {
"balance": "0x1"
},
"0000000000000000000000000000000000000072": {
"balance": "0x1"
},
"0000000000000000000000000000000000000073": {
"balance": "0x1"
},
"0000000000000000000000000000000000000074": {
"balance": "0x1"
},
"0000000000000000000000000000000000000075": {
"balance": "0x1"
},
"0000000000000000000000000000000000000076": {
"balance": "0x1"
},
"0000000000000000000000000000000000000077": {
"balance": "0x1"
},
"0000000000000000000000000000000000000078": {
"balance": "0x1"
},
"0000000000000000000000000000000000000079": {
"balance": "0x1"
},
"000000000000000000000000000000000000007a": {
"balance": "0x1"
},
"000000000000000000000000000000000000007b": {
"balance": "0x1"
},
"000000000000000000000000000000000000007c": {
"balance": "0x1"
},
"000000000000000000000000000000000000007d": {
"balance": "0x1"
},
"000000000000000000000000000000000000007e": {
"balance": "0x1"
},
"000000000000000000000000000000000000007f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000080": {
"balance": "0x1"
},
"0000000000000000000000000000000000000081": {
"balance": "0x1"
},
"0000000000000000000000000000000000000082": {
"balance": "0x1"
},
"0000000000000000000000000000000000000083": {
"balance": "0x1"
},
"0000000000000000000000000000000000000084": {
"balance": "0x1"
},
"0000000000000000000000000000000000000085": {
"balance": "0x1"
},
"0000000000000000000000000000000000000086": {
"balance": "0x1"
},
"0000000000000000000000000000000000000087": {
"balance": "0x1"
},
"0000000000000000000000000000000000000088": {
"balance": "0x1"
},
"0000000000000000000000000000000000000089": {
"balance": "0x1"
},
"000000000000000000000000000000000000008a": {
"balance": "0x1"
},
"000000000000000000000000000000000000008b": {
"balance": "0x1"
},
"000000000000000000000000000000000000008c": {
"balance": "0x1"
},
"000000000000000000000000000000000000008d": {
"balance": "0x1"
},
"000000000000000000000000000000000000008e": {
"balance": "0x1"
},
"000000000000000000000000000000000000008f": {
"balance": "0x1"
},
"0000000000000000000000000000000000000090": {
"balance": "0x1"
},
"0000000000000000000000000000000000000091": {
"balance": "0x1"
},
"0000000000000000000000000000000000000092": {
"balance": "0x1"
},
"0000000000000000000000000000000000000093": {
"balance": "0x1"
},
"0000000000000000000000000000000000000094": {
"balance": "0x1"
},
"0000000000000000000000000000000000000095": {
"balance": "0x1"
},
"0000000000000000000000000000000000000096": {
"balance": "0x1"
},
"0000000000000000000000000000000000000097": {
"balance": "0x1"
},
"0000000000000000000000000000000000000098": {
"balance": "0x1"
},
"0000000000000000000000000000000000000099": {
"balance": "0x1"
},
"000000000000000000000000000000000000009a": {
"balance": "0x1"
},
"000000000000000000000000000000000000009b": {
"balance": "0x1"
},
"000000000000000000000000000000000000009c": {
"balance": "0x1"
},
"000000000000000000000000000000000000009d": {
"balance": "0x1"
},
"000000000000000000000000000000000000009e": {
"balance": "0x1"
},
"000000000000000000000000000000000000009f": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a0": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a1": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a2": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a3": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a4": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a5": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a6": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a7": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a8": {
"balance": "0x1"
},
"00000000000000000000000000000000000000a9": {
"balance": "0x1"
},
"00000000000000000000000000000000000000aa": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ab": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ac": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ad": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ae": {
"balance": "0x1"
},
"00000000000000000000000000000000000000af": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b0": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b1": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b2": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b3": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b4": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b5": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b6": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b7": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b8": {
"balance": "0x1"
},
"00000000000000000000000000000000000000b9": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ba": {
"balance": "0x1"
},
"00000000000000000000000000000000000000bb": {
"balance": "0x1"
},
"00000000000000000000000000000000000000bc": {
"balance": "0x1"
},
"00000000000000000000000000000000000000bd": {
"balance": "0x1"
},
"00000000000000000000000000000000000000be": {
"balance": "0x1"
},
"00000000000000000000000000000000000000bf": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c0": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c1": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c2": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c3": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c4": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c5": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c6": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c7": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c8": {
"balance": "0x1"
},
"00000000000000000000000000000000000000c9": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ca": {
"balance": "0x1"
},
"00000000000000000000000000000000000000cb": {
"balance": "0x1"
},
"00000000000000000000000000000000000000cc": {
"balance": "0x1"
},
"00000000000000000000000000000000000000cd": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ce": {
"balance": "0x1"
},
"00000000000000000000000000000000000000cf": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d0": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d1": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d2": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d3": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d4": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d5": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d6": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d7": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d8": {
"balance": "0x1"
},
"00000000000000000000000000000000000000d9": {
"balance": "0x1"
},
"00000000000000000000000000000000000000da": {
"balance": "0x1"
},
"00000000000000000000000000000000000000db": {
"balance": "0x1"
},
"00000000000000000000000000000000000000dc": {
"balance": "0x1"
},
"00000000000000000000000000000000000000dd": {
"balance": "0x1"
},
"00000000000000000000000000000000000000de": {
"balance": "0x1"
},
"00000000000000000000000000000000000000df": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e0": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e1": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e2": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e3": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e4": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e5": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e6": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e7": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e8": {
"balance": "0x1"
},
"00000000000000000000000000000000000000e9": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ea": {
"balance": "0x1"
},
"00000000000000000000000000000000000000eb": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ec": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ed": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ee": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ef": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f0": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f1": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f2": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f3": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f4": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f5": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f6": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f7": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f8": {
"balance": "0x1"
},
"00000000000000000000000000000000000000f9": {
"balance": "0x1"
},
"00000000000000000000000000000000000000fa": {
"balance": "0x1"
},
"00000000000000000000000000000000000000fb": {
"balance": "0x1"
},
"00000000000000000000000000000000000000fc": {
"balance": "0x1"
},
"00000000000000000000000000000000000000fd": {
"balance": "0x1"
},
"00000000000000000000000000000000000000fe": {
"balance": "0x1"
},
"00000000000000000000000000000000000000ff": {
"balance": "0x1"
},
"de3829a23df1479438622a08a116e8eb3f620bb5": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
},
"f39fd6e51aad88f6f4ce6ab8827279cfffb92266": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
},
"4200000000000000000000000000000000000014": {
"code": "",
"balance": "0x0"
},
"4200000000000000000000000000000000000015": {
"code": "",
"balance": "0x0"
},
"4200000000000000000000000000000000000016": {
"code": "",
"balance": "0x0"
},
"70997970C51812dc3A010C7d01b50e0d17dc79C8": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
}
},
"number": "0x0",
"gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"baseFeePerGas": "0x7"
}
......@@ -6,6 +6,6 @@ COPY --from=geth /usr/local/bin/abigen /usr/local/bin/abigen
RUN apk add --no-cache make gcc musl-dev linux-headers git jq curl bash gzip ca-certificates openssh && \
go install gotest.tools/gotestsum@latest && \
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.45.2
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.46.2
CMD ["bash"]
......@@ -41,7 +41,8 @@
"postinstall": "patch-package",
"ready": "yarn lint && yarn test",
"prepare": "husky install",
"release": "yarn build && yarn changeset publish"
"release": "yarn build && yarn changeset publish",
"update:yarn": "yarn set version 1.x"
},
"devDependencies": {
"@babel/eslint-parser": "^7.18.2",
......
......@@ -144,17 +144,19 @@ export abstract class BaseServiceV2<
* @param params.port Port for the app server. Defaults to 7300.
* @param params.hostname Hostname for the app server. Defaults to 0.0.0.0.
*/
constructor(params: {
name: string
version: string
optionsSpec: OptionsSpec<TOptions>
metricsSpec: MetricsSpec<TMetrics>
options?: Partial<TOptions>
loop?: boolean
loopIntervalMs?: number
port?: number
hostname?: string
}) {
constructor(
private readonly params: {
name: string
version: string
optionsSpec: OptionsSpec<TOptions>
metricsSpec: MetricsSpec<TMetrics>
options?: Partial<TOptions>
loop?: boolean
loopIntervalMs?: number
port?: number
hostname?: string
}
) {
this.loop = params.loop !== undefined ? params.loop : true
this.state = {} as TServiceState
......@@ -404,6 +406,7 @@ export abstract class BaseServiceV2<
app.get('/healthz', async (req, res) => {
return res.json({
ok: this.healthy,
version: this.params.version,
})
})
......@@ -429,7 +432,7 @@ export abstract class BaseServiceV2<
}
return '/invalid_path_not_a_real_route'
}
},
})
)
......
......@@ -8,3 +8,4 @@ forge-artifacts
cache
typechain
coverage*
deployments
......@@ -39,7 +39,7 @@ L1StandardBridge_Test:test_depositERC20() (gas: 452856)
L1StandardBridge_Test:test_depositERC20To() (gas: 454632)
L1StandardBridge_Test:test_depositETH() (gas: 247077)
L1StandardBridge_Test:test_depositETHTo() (gas: 204961)
L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 438752)
L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 438745)
L1StandardBridge_Test:test_finalizeETHWithdrawal() (gas: 48005)
L1StandardBridge_Test:test_initialize() (gas: 14885)
L1StandardBridge_Test:test_onlyEOADepositERC20() (gas: 12085)
......@@ -57,21 +57,27 @@ L2CrossDomainMessenger_Test:test_L2MessengerSendMessage() (gas: 119682)
L2CrossDomainMessenger_Test:test_L2MessengerTwiceSendMessage() (gas: 133142)
L2CrossDomainMessenger_Test:test_L2MessengerXDomainSenderReverts() (gas: 10599)
L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 54881)
L2OutputOracleTest:testCannot_appendEmptyOutput() (gas: 18442)
L2OutputOracleTest:testCannot_appendFutureTimetamp() (gas: 20072)
L2OutputOracleTest:testCannot_appendOnWrongFork() (gas: 20710)
L2OutputOracleTest:testCannot_appendOutputIfNotSequencer() (gas: 17829)
L2OutputOracleTest:testCannot_appendUnexpectedBlockNumber() (gas: 20313)
L2OutputOracleTest:testCannot_deleteL2Output_ifNotSequencer() (gas: 18805)
L2OutputOracleTest:testCannot_deleteWrongL2Output() (gas: 79498)
L2OutputOracleTest:test_appendWithBlockhashAndHeight() (gas: 69365)
L2OutputOracleTest:test_appendingAnotherOutput() (gas: 70714)
L2OutputOracleTest:test_computeL2Timestamp() (gas: 19230)
L2OutputOracleTest:test_constructor() (gas: 33908)
L2OutputOracleTest:test_deleteL2Output() (gas: 66081)
L2OutputOracleTest:test_getL2Output() (gas: 76274)
L2OutputOracleTest:test_latestBlockNumber() (gas: 70075)
L2OutputOracleTest:test_nextBlockNumber() (gas: 9279)
L2OutputOracleTest:testCannot_appendEmptyOutput() (gas: 18216)
L2OutputOracleTest:testCannot_appendFutureTimetamp() (gas: 20183)
L2OutputOracleTest:testCannot_appendOnWrongFork() (gas: 20462)
L2OutputOracleTest:testCannot_appendOutputIfNotSequencer() (gas: 17607)
L2OutputOracleTest:testCannot_appendUnexpectedBlockNumber() (gas: 20086)
L2OutputOracleTest:testCannot_deleteL2Output_ifNotOwner() (gas: 18893)
L2OutputOracleTest:testCannot_deleteL2Output_withWrongRoot() (gas: 83353)
L2OutputOracleTest:testCannot_deleteL2Output_withWrongTime() (gas: 79346)
L2OutputOracleTest:test_appendWithBlockhashAndHeight() (gas: 69126)
L2OutputOracleTest:test_appendingAnotherOutput() (gas: 70475)
L2OutputOracleTest:test_changeSequencer() (gas: 35473)
L2OutputOracleTest:test_computeL2Timestamp() (gas: 19323)
L2OutputOracleTest:test_constructor() (gas: 40152)
L2OutputOracleTest:test_deleteL2Output() (gas: 69237)
L2OutputOracleTest:test_getL2Output() (gas: 76099)
L2OutputOracleTest:test_latestBlockNumber() (gas: 69878)
L2OutputOracleTest:test_nextBlockNumber() (gas: 9281)
L2OutputOracleTest:test_updateOwner() (gas: 24185)
L2OutputOracleUpgradeable_Test:test_cannotInitImpl() (gas: 8431)
L2OutputOracleUpgradeable_Test:test_cannotInitProxy() (gas: 13430)
L2OutputOracleUpgradeable_Test:test_initValuesOnProxy() (gas: 38906)
L2StandardBridge_Test:test_ERC20BridgeFailed_whenLocalTokenIsBridge() (gas: 133097)
L2StandardBridge_Test:test_cannotWithdrawEthWithoutSendingIt() (gas: 21611)
L2StandardBridge_Test:test_finalizeDeposit() (gas: 93100)
......@@ -110,7 +116,7 @@ OptimismMintableTokenFactory_Test:test_initializeShouldRevert() (gas: 12696)
OptimismPortal_Test:test_OptimismPortalConstructor() (gas: 11413)
OptimismPortal_Test:test_OptimismPortalContractCreationReverts() (gas: 9214)
OptimismPortal_Test:test_OptimismPortalReceiveEth() (gas: 121706)
OptimismPortal_Test:test_cannotVerifyRecentWithdrawal() (gas: 21886)
OptimismPortal_Test:test_cannotVerifyRecentWithdrawal() (gas: 21908)
OptimismPortal_Test:test_depositTransaction_NoValueContract() (gas: 70746)
OptimismPortal_Test:test_depositTransaction_NoValueEOA() (gas: 71114)
OptimismPortal_Test:test_depositTransaction_createWithZeroValueForContract() (gas: 70773)
......@@ -119,7 +125,7 @@ OptimismPortal_Test:test_depositTransaction_withEthValueAndContractContractCreat
OptimismPortal_Test:test_depositTransaction_withEthValueAndEOAContractCreation() (gas: 69947)
OptimismPortal_Test:test_depositTransaction_withEthValueFromContract() (gas: 77478)
OptimismPortal_Test:test_depositTransaction_withEthValueFromEOA() (gas: 78049)
OptimismPortal_Test:test_invalidWithdrawalProof() (gas: 33702)
OptimismPortal_Test:test_invalidWithdrawalProof() (gas: 33769)
Proxy_Test:test_clashingFunctionSignatures() (gas: 101427)
Proxy_Test:test_implementationKey() (gas: 20942)
Proxy_Test:test_implementationProxyCallIfNotAdmin() (gas: 30021)
......
......@@ -9,6 +9,7 @@ forge-artifacts
cache
typechain
coverage*
deployments
contracts/L2/WETH9.sol
......
=======================
👁👁 STORAGE LAYOUT snapshot 👁👁
=======================
=======================
➡ L1CrossDomainMessenger
=======================
+---------------------------+--------------------------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+==============================================================================+
| _initialized | uint8 | 0 | 0 | 1 |
|---------------------------+--------------------------+------+--------+-------|
| _initializing | bool | 0 | 1 | 1 |
|---------------------------+--------------------------+------+--------+-------|
| __gap | uint256[50] | 1 | 0 | 1600 |
|---------------------------+--------------------------+------+--------+-------|
| _owner | address | 51 | 0 | 20 |
|---------------------------+--------------------------+------+--------+-------|
| __gap | uint256[49] | 52 | 0 | 1568 |
|---------------------------+--------------------------+------+--------+-------|
| _paused | bool | 101 | 0 | 1 |
|---------------------------+--------------------------+------+--------+-------|
| __gap | uint256[49] | 102 | 0 | 1568 |
|---------------------------+--------------------------+------+--------+-------|
| _status | uint256 | 151 | 0 | 32 |
|---------------------------+--------------------------+------+--------+-------|
| __gap | uint256[49] | 152 | 0 | 1568 |
|---------------------------+--------------------------+------+--------+-------|
| REMOVED_VARIABLE_SPACER_1 | bytes32 | 201 | 0 | 32 |
|---------------------------+--------------------------+------+--------+-------|
| REMOVED_VARIABLE_SPACER_2 | bytes32 | 202 | 0 | 32 |
|---------------------------+--------------------------+------+--------+-------|
| successfulMessages | mapping(bytes32 => bool) | 203 | 0 | 32 |
|---------------------------+--------------------------+------+--------+-------|
| xDomainMsgSender | address | 204 | 0 | 20 |
|---------------------------+--------------------------+------+--------+-------|
| msgNonce | uint256 | 205 | 0 | 32 |
|---------------------------+--------------------------+------+--------+-------|
| otherMessenger | address | 206 | 0 | 20 |
|---------------------------+--------------------------+------+--------+-------|
| receivedMessages | mapping(bytes32 => bool) | 207 | 0 | 32 |
|---------------------------+--------------------------+------+--------+-------|
| blockedSystemAddresses | mapping(address => bool) | 208 | 0 | 32 |
|---------------------------+--------------------------+------+--------+-------|
| portal | contract OptimismPortal | 209 | 0 | 20 |
+---------------------------+--------------------------+------+--------+-------+
=======================
➡ L1StandardBridge
=======================
+-------------+-------------------------------------------------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+=======================================================================================+
| messenger | contract CrossDomainMessenger | 0 | 0 | 20 |
|-------------+-------------------------------------------------+------+--------+-------|
| otherBridge | contract StandardBridge | 1 | 0 | 20 |
|-------------+-------------------------------------------------+------+--------+-------|
| deposits | mapping(address => mapping(address => uint256)) | 2 | 0 | 32 |
+-------------+-------------------------------------------------+------+--------+-------+
=======================
➡ L2OutputOracle
=======================
+-------------------+----------------------------------------------------------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+======================================================================================================+
| _initialized | uint8 | 0 | 0 | 1 |
|-------------------+----------------------------------------------------------+------+--------+-------|
| _initializing | bool | 0 | 1 | 1 |
|-------------------+----------------------------------------------------------+------+--------+-------|
| __gap | uint256[50] | 1 | 0 | 1600 |
|-------------------+----------------------------------------------------------+------+--------+-------|
| _owner | address | 51 | 0 | 20 |
|-------------------+----------------------------------------------------------+------+--------+-------|
| __gap | uint256[49] | 52 | 0 | 1568 |
|-------------------+----------------------------------------------------------+------+--------+-------|
| sequencer | address | 101 | 0 | 20 |
|-------------------+----------------------------------------------------------+------+--------+-------|
| latestBlockNumber | uint256 | 102 | 0 | 32 |
|-------------------+----------------------------------------------------------+------+--------+-------|
| l2Outputs | mapping(uint256 => struct L2OutputOracle.OutputProposal) | 103 | 0 | 32 |
+-------------------+----------------------------------------------------------+------+--------+-------+
=======================
➡ OptimismPortal
=======================
+----------------------+----------------------------------------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+=======================================================================================+
| params | struct ResourceMetering.ResourceParams | 0 | 0 | 32 |
|----------------------+----------------------------------------+------+--------+-------|
| l2Sender | address | 1 | 0 | 20 |
|----------------------+----------------------------------------+------+--------+-------|
| finalizedWithdrawals | mapping(bytes32 => bool) | 2 | 0 | 32 |
+----------------------+----------------------------------------+------+--------+-------+
=======================
➡ DeployerWhitelist
=======================
+-----------+--------------------------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+==============================================================+
| owner | address | 0 | 0 | 20 |
|-----------+--------------------------+------+--------+-------|
| whitelist | mapping(address => bool) | 1 | 0 | 32 |
+-----------+--------------------------+------+--------+-------+
=======================
➡ GasPriceOracle
=======================
+----------+---------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+============================================+
| _owner | address | 0 | 0 | 20 |
|----------+---------+------+--------+-------|
| spacer0 | uint256 | 1 | 0 | 32 |
|----------+---------+------+--------+-------|
| spacer1 | uint256 | 2 | 0 | 32 |
|----------+---------+------+--------+-------|
| overhead | uint256 | 3 | 0 | 32 |
|----------+---------+------+--------+-------|
| scalar | uint256 | 4 | 0 | 32 |
|----------+---------+------+--------+-------|
| decimals | uint256 | 5 | 0 | 32 |
+----------+---------+------+--------+-------+
=======================
➡ L1Block
=======================
+----------------+---------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+==================================================+
| number | uint64 | 0 | 0 | 8 |
|----------------+---------+------+--------+-------|
| timestamp | uint64 | 0 | 8 | 8 |
|----------------+---------+------+--------+-------|
| basefee | uint256 | 1 | 0 | 32 |
|----------------+---------+------+--------+-------|
| hash | bytes32 | 2 | 0 | 32 |
|----------------+---------+------+--------+-------|
| sequenceNumber | uint64 | 3 | 0 | 8 |
+----------------+---------+------+--------+-------+
=======================
➡ L1BlockNumber
=======================
+------+------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+=====================================+
+------+------+------+--------+-------+
=======================
➡ L2CrossDomainMessenger
=======================
+---------------------------+--------------------------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+==============================================================================+
| _initialized | uint8 | 0 | 0 | 1 |
|---------------------------+--------------------------+------+--------+-------|
| _initializing | bool | 0 | 1 | 1 |
|---------------------------+--------------------------+------+--------+-------|
| __gap | uint256[50] | 1 | 0 | 1600 |
|---------------------------+--------------------------+------+--------+-------|
| _owner | address | 51 | 0 | 20 |
|---------------------------+--------------------------+------+--------+-------|
| __gap | uint256[49] | 52 | 0 | 1568 |
|---------------------------+--------------------------+------+--------+-------|
| _paused | bool | 101 | 0 | 1 |
|---------------------------+--------------------------+------+--------+-------|
| __gap | uint256[49] | 102 | 0 | 1568 |
|---------------------------+--------------------------+------+--------+-------|
| _status | uint256 | 151 | 0 | 32 |
|---------------------------+--------------------------+------+--------+-------|
| __gap | uint256[49] | 152 | 0 | 1568 |
|---------------------------+--------------------------+------+--------+-------|
| REMOVED_VARIABLE_SPACER_1 | bytes32 | 201 | 0 | 32 |
|---------------------------+--------------------------+------+--------+-------|
| REMOVED_VARIABLE_SPACER_2 | bytes32 | 202 | 0 | 32 |
|---------------------------+--------------------------+------+--------+-------|
| successfulMessages | mapping(bytes32 => bool) | 203 | 0 | 32 |
|---------------------------+--------------------------+------+--------+-------|
| xDomainMsgSender | address | 204 | 0 | 20 |
|---------------------------+--------------------------+------+--------+-------|
| msgNonce | uint256 | 205 | 0 | 32 |
|---------------------------+--------------------------+------+--------+-------|
| otherMessenger | address | 206 | 0 | 20 |
|---------------------------+--------------------------+------+--------+-------|
| receivedMessages | mapping(bytes32 => bool) | 207 | 0 | 32 |
|---------------------------+--------------------------+------+--------+-------|
| blockedSystemAddresses | mapping(address => bool) | 208 | 0 | 32 |
+---------------------------+--------------------------+------+--------+-------+
=======================
➡ L2StandardBridge
=======================
+-------------+-------------------------------------------------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+=======================================================================================+
| messenger | contract CrossDomainMessenger | 0 | 0 | 20 |
|-------------+-------------------------------------------------+------+--------+-------|
| otherBridge | contract StandardBridge | 1 | 0 | 20 |
|-------------+-------------------------------------------------+------+--------+-------|
| deposits | mapping(address => mapping(address => uint256)) | 2 | 0 | 32 |
+-------------+-------------------------------------------------+------+--------+-------+
=======================
➡ L2ToL1MessagePasser
=======================
+--------------+--------------------------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+=================================================================+
| sentMessages | mapping(bytes32 => bool) | 0 | 0 | 32 |
|--------------+--------------------------+------+--------+-------|
| nonce | uint256 | 1 | 0 | 32 |
+--------------+--------------------------+------+--------+-------+
=======================
➡ OVM_ETH
=======================
+--------------+-------------------------------------------------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+========================================================================================+
| _balances | mapping(address => uint256) | 0 | 0 | 32 |
|--------------+-------------------------------------------------+------+--------+-------|
| _allowances | mapping(address => mapping(address => uint256)) | 1 | 0 | 32 |
|--------------+-------------------------------------------------+------+--------+-------|
| _totalSupply | uint256 | 2 | 0 | 32 |
|--------------+-------------------------------------------------+------+--------+-------|
| _name | string | 3 | 0 | 32 |
|--------------+-------------------------------------------------+------+--------+-------|
| _symbol | string | 4 | 0 | 32 |
|--------------+-------------------------------------------------+------+--------+-------|
| remoteToken | address | 5 | 0 | 20 |
|--------------+-------------------------------------------------+------+--------+-------|
| bridge | address | 6 | 0 | 20 |
+--------------+-------------------------------------------------+------+--------+-------+
=======================
➡ SequencerFeeVault
=======================
+-------------+---------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+===============================================+
| l1FeeWallet | address | 0 | 0 | 20 |
+-------------+---------+------+--------+-------+
=======================
➡ WETH9
=======================
+-----------+-------------------------------------------------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+=====================================================================================+
| name | string | 0 | 0 | 32 |
|-----------+-------------------------------------------------+------+--------+-------|
| symbol | string | 1 | 0 | 32 |
|-----------+-------------------------------------------------+------+--------+-------|
| decimals | uint8 | 2 | 0 | 1 |
|-----------+-------------------------------------------------+------+--------+-------|
| balanceOf | mapping(address => uint256) | 3 | 0 | 32 |
|-----------+-------------------------------------------------+------+--------+-------|
| allowance | mapping(address => mapping(address => uint256)) | 4 | 0 | 32 |
+-----------+-------------------------------------------------+------+--------+-------+
=======================
➡ ProxyAdmin
=======================
+--------------------+-----------------------------------------------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+============================================================================================+
| owner | address | 0 | 0 | 20 |
|--------------------+-----------------------------------------------+------+--------+-------|
| proxyType | mapping(address => enum ProxyAdmin.ProxyType) | 1 | 0 | 32 |
|--------------------+-----------------------------------------------+------+--------+-------|
| implementationName | mapping(address => string) | 2 | 0 | 32 |
|--------------------+-----------------------------------------------+------+--------+-------|
| addressManager | contract Lib_AddressManager | 3 | 0 | 20 |
|--------------------+-----------------------------------------------+------+--------+-------|
| upgrading | bool | 3 | 20 | 1 |
+--------------------+-----------------------------------------------+------+--------+-------+
=======================
➡ Proxy
=======================
+------+------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+=====================================+
+------+------+------+--------+-------+
=======================
➡ L1ChugSplashProxy
=======================
+------+------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+=====================================+
+------+------+------+--------+-------+
=======================
➡ OptimismMintableERC20
=======================
+--------------+-------------------------------------------------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+========================================================================================+
| _balances | mapping(address => uint256) | 0 | 0 | 32 |
|--------------+-------------------------------------------------+------+--------+-------|
| _allowances | mapping(address => mapping(address => uint256)) | 1 | 0 | 32 |
|--------------+-------------------------------------------------+------+--------+-------|
| _totalSupply | uint256 | 2 | 0 | 32 |
|--------------+-------------------------------------------------+------+--------+-------|
| _name | string | 3 | 0 | 32 |
|--------------+-------------------------------------------------+------+--------+-------|
| _symbol | string | 4 | 0 | 32 |
|--------------+-------------------------------------------------+------+--------+-------|
| remoteToken | address | 5 | 0 | 20 |
|--------------+-------------------------------------------------+------+--------+-------|
| bridge | address | 6 | 0 | 20 |
+--------------+-------------------------------------------------+------+--------+-------+
=======================
➡ OptimismMintableTokenFactory
=======================
+--------+---------+------+--------+-------+
| Name | Type | Slot | Offset | Bytes |
+==========================================+
| bridge | address | 0 | 0 | 20 |
+--------+---------+------+--------+-------+
//SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import {
OwnableUpgradeable
} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
/**
* @title L2OutputOracle
......@@ -10,7 +12,12 @@ import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
* This contract should be deployed behind an upgradable proxy
*/
// slither-disable-next-line locked-ether
contract L2OutputOracle is Ownable {
contract L2OutputOracle is OwnableUpgradeable {
/**
* @notice Contract version number.
*/
uint8 public constant L2_OUTPUT_ORACLE_VERSION = 1;
/**
* @notice OutputProposal represents a commitment to the L2 state.
* The timestamp is the L1 timestamp that the output root is posted.
......@@ -48,6 +55,14 @@ contract L2OutputOracle is Ownable {
uint256 indexed _l2BlockNumber
);
/**
* @notice Emitted when the sequencer address is changed.
*
* @param previousSequencer The previous sequencer address.
* @param newSequencer The new sequencer address.
*/
event SequencerChanged(address indexed previousSequencer, address indexed newSequencer);
/**
* @notice The interval in L2 blocks at which checkpoints must be submitted.
*/
......@@ -73,6 +88,11 @@ contract L2OutputOracle is Ownable {
*/
uint256 public immutable L2_BLOCK_TIME;
/**
* @notice The address of the sequencer;
*/
address public sequencer;
/**
* @notice The number of the most recent L2 block recorded in this contract.
*/
......@@ -85,6 +105,14 @@ contract L2OutputOracle is Ownable {
*/
mapping(uint256 => OutputProposal) internal l2Outputs;
/**
* @notice Reverts if called by any account other than the sequencer.
*/
modifier onlySequencer() {
require(sequencer == msg.sender, "OutputOracle: caller is not the sequencer");
_;
}
/**
* @notice Initialize the L2OutputOracle contract.
*
......@@ -97,6 +125,7 @@ contract L2OutputOracle is Ownable {
* @param _startingTimestamp The timestamp of the first L2 block.
* @param _l2BlockTime The timestamp of the first L2 block.
* @param _sequencer The address of the sequencer.
* @param _owner The address of the owner.
*/
constructor(
uint256 _submissionInterval,
......@@ -105,7 +134,8 @@ contract L2OutputOracle is Ownable {
uint256 _startingBlockNumber,
uint256 _startingTimestamp,
uint256 _l2BlockTime,
address _sequencer
address _sequencer,
address _owner
) {
require(
_l2BlockTime < block.timestamp,
......@@ -117,10 +147,29 @@ contract L2OutputOracle is Ownable {
STARTING_TIMESTAMP = _startingTimestamp;
L2_BLOCK_TIME = _l2BlockTime;
initialize(_genesisL2Output, _startingBlockNumber, _sequencer, _owner);
}
/**
* @notice Initialize the L2OutputOracle contract.
*
* @param _genesisL2Output The initial L2 output of the L2 chain.
* @param _startingBlockNumber The timestamp to start L2 block at.
* @param _sequencer The address of the sequencer.
* @param _owner The address of the owner.
*/
function initialize(
bytes32 _genesisL2Output,
uint256 _startingBlockNumber,
address _sequencer,
address _owner
) public reinitializer(L2_OUTPUT_ORACLE_VERSION) {
l2Outputs[_startingBlockNumber] = OutputProposal(_genesisL2Output, block.timestamp);
latestBlockNumber = _startingBlockNumber;
__Ownable_init();
_transferOwnership(_sequencer);
changeSequencer(_sequencer);
_transferOwnership(_owner);
}
/**
......@@ -139,7 +188,7 @@ contract L2OutputOracle is Ownable {
uint256 _l2BlockNumber,
bytes32 _l1Blockhash,
uint256 _l1BlockNumber
) external payable onlyOwner {
) external payable onlySequencer {
require(
_l2BlockNumber == nextBlockNumber(),
"OutputOracle: Block number must be equal to next expected block number."
......@@ -172,8 +221,11 @@ contract L2OutputOracle is Ownable {
}
/**
* @notice Deletes the most recent output.
*
* @notice Deletes the most recent output. This is used to remove the most recent output in the
* event that an erreneous output is submitted. It can only be called by the contract's
* owner, not the sequencer. Longer term, this should be replaced with a more robust
* mechanism which will allow deletion of proposals shown to be invalid by a fault
* proof.
* @param _proposal Represents the output proposal to delete
*/
function deleteL2Output(OutputProposal memory _proposal) external onlyOwner {
......@@ -230,4 +282,15 @@ contract L2OutputOracle is Ownable {
return
STARTING_TIMESTAMP + ((_l2BlockNumber - STARTING_BLOCK_NUMBER) * SUBMISSION_INTERVAL);
}
/**
* @notice Transfers the sequencer role to a new account (`newSequencer`).
* Can only be called by the current owner.
*/
function changeSequencer(address _newSequencer) public onlyOwner {
require(_newSequencer != address(0), "OutputOracle: new sequencer is the zero address");
require(_newSequencer != owner(), "OutputOracle: sequencer cannot be same as the owner");
emit SequencerChanged(sequencer, _newSequencer);
sequencer = _newSequencer;
}
}
......@@ -42,18 +42,20 @@ contract CommonTest is Test {
vm.fee(1000000000);
}
}
contract L2OutputOracle_Initializer is CommonTest {
// Test target
L2OutputOracle oracle;
// Constructor arguments
uint256 submissionInterval = 42;
address sequencer = 0x000000000000000000000000000000000000AbBa;
address owner = 0x000000000000000000000000000000000000ACDC;
uint256 submissionInterval = 1800;
uint256 l2BlockTime = 2;
bytes32 genesisL2Output = keccak256(abi.encode(0));
uint256 historicalTotalBlocks = 199;
uint256 startingBlockNumber = 200;
uint256 startingTimestamp = 1000;
uint256 l2BlockTime = 2;
address sequencer = 0x000000000000000000000000000000000000AbBa;
// Test data
uint256 initL1Time;
......@@ -74,7 +76,8 @@ contract L2OutputOracle_Initializer is CommonTest {
startingBlockNumber,
startingTimestamp,
l2BlockTime,
sequencer
sequencer,
owner
);
}
}
......@@ -82,8 +85,10 @@ contract L2OutputOracle_Initializer is CommonTest {
contract Messenger_Initializer is L2OutputOracle_Initializer {
OptimismPortal op;
L1CrossDomainMessenger L1Messenger;
L2CrossDomainMessenger L2Messenger = L2CrossDomainMessenger(Lib_PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER);
L2ToL1MessagePasser messagePasser = L2ToL1MessagePasser(payable(Lib_PredeployAddresses.L2_TO_L1_MESSAGE_PASSER));
L2CrossDomainMessenger L2Messenger =
L2CrossDomainMessenger(Lib_PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER);
L2ToL1MessagePasser messagePasser =
L2ToL1MessagePasser(payable(Lib_PredeployAddresses.L2_TO_L1_MESSAGE_PASSER));
event SentMessage(
address indexed target,
......@@ -139,20 +144,11 @@ contract Messenger_Initializer is L2OutputOracle_Initializer {
address(new L2ToL1MessagePasser()).code
);
vm.label(
Lib_PredeployAddresses.OVM_ETH,
"OVM_ETH"
);
vm.label(Lib_PredeployAddresses.OVM_ETH, "OVM_ETH");
vm.label(
Lib_PredeployAddresses.L2_TO_L1_MESSAGE_PASSER,
"L2ToL1MessagePasser"
);
vm.label(Lib_PredeployAddresses.L2_TO_L1_MESSAGE_PASSER, "L2ToL1MessagePasser");
vm.label(
Lib_PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER,
"L2CrossDomainMessenger"
);
vm.label(Lib_PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER, "L2CrossDomainMessenger");
vm.label(
AddressAliasHelper.applyL1ToL2Alias(address(L1Messenger)),
......@@ -274,14 +270,8 @@ contract Bridge_Initializer is Messenger_Initializer {
function setUp() public virtual override {
super.setUp();
vm.label(
Lib_PredeployAddresses.L2_STANDARD_BRIDGE,
"L2StandardBridge"
);
vm.label(
Lib_PredeployAddresses.L2_STANDARD_TOKEN_FACTORY,
"L2StandardTokenFactory"
);
vm.label(Lib_PredeployAddresses.L2_STANDARD_BRIDGE, "L2StandardBridge");
vm.label(Lib_PredeployAddresses.L2_STANDARD_TOKEN_FACTORY, "L2StandardTokenFactory");
// Deploy the L1 bridge and initialize it with the address of the
// L1CrossDomainMessenger
......@@ -299,32 +289,34 @@ contract Bridge_Initializer is Messenger_Initializer {
// Set up the L2 mintable token factory
OptimismMintableTokenFactory factory = new OptimismMintableTokenFactory();
vm.etch(Lib_PredeployAddresses.L2_STANDARD_TOKEN_FACTORY, address(factory).code);
L2TokenFactory = OptimismMintableTokenFactory(Lib_PredeployAddresses.L2_STANDARD_TOKEN_FACTORY);
L2TokenFactory = OptimismMintableTokenFactory(
Lib_PredeployAddresses.L2_STANDARD_TOKEN_FACTORY
);
L2TokenFactory.initialize(Lib_PredeployAddresses.L2_STANDARD_BRIDGE);
vm.etch(
Lib_PredeployAddresses.OVM_ETH,
address(new OVM_ETH()).code
);
vm.etch(Lib_PredeployAddresses.OVM_ETH, address(new OVM_ETH()).code);
L1Token = new ERC20("Native L1 Token", "L1T");
// Deploy the L2 ERC20 now
L2Token = OptimismMintableERC20(L2TokenFactory.createStandardL2Token(
address(L1Token),
string(abi.encodePacked("L2-", L1Token.name())),
string(abi.encodePacked("L2-", L1Token.symbol()))
));
L2Token = OptimismMintableERC20(
L2TokenFactory.createStandardL2Token(
address(L1Token),
string(abi.encodePacked("L2-", L1Token.name())),
string(abi.encodePacked("L2-", L1Token.symbol()))
)
);
NativeL2Token = new ERC20("Native L2 Token", "L2T");
L1TokenFactory = new OptimismMintableTokenFactory();
L1TokenFactory.initialize(address(L1Bridge));
RemoteL1Token = OptimismMintableERC20(L1TokenFactory.createStandardL2Token(
address(NativeL2Token),
string(abi.encodePacked("L1-", NativeL2Token.name())),
string(abi.encodePacked("L1-", NativeL2Token.symbol()))
));
RemoteL1Token = OptimismMintableERC20(
L1TokenFactory.createStandardL2Token(
address(NativeL2Token),
string(abi.encodePacked("L1-", NativeL2Token.name())),
string(abi.encodePacked("L1-", NativeL2Token.symbol()))
)
);
}
}
......@@ -3,6 +3,7 @@ pragma solidity 0.8.10;
import { L2OutputOracle_Initializer } from "./CommonTest.t.sol";
import { L2OutputOracle } from "../L1/L2OutputOracle.sol";
import { Proxy } from "../universal/Proxy.sol";
contract L2OutputOracleTest is L2OutputOracle_Initializer {
bytes32 appendedOutput1 = keccak256(abi.encode(1));
......@@ -11,19 +12,20 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
super.setUp();
}
// advance the evm state to meet the L2OutputOracle's requirements for appendL2Output
function oracleWarpRoll(uint256 _nextBlockNumber) public {
vm.roll(_nextBlockNumber);
// Advance the evm's time to meet the L2OutputOracle's requirements for appendL2Output
function warpToAppendTime(uint256 _nextBlockNumber) public {
vm.warp(oracle.computeL2Timestamp(_nextBlockNumber) + 1);
}
function test_constructor() external {
assertEq(oracle.owner(), sequencer);
assertEq(oracle.owner(), owner);
assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval);
assertEq(oracle.HISTORICAL_TOTAL_BLOCKS(), historicalTotalBlocks);
assertEq(oracle.latestBlockNumber(), startingBlockNumber);
assertEq(oracle.STARTING_BLOCK_NUMBER(), startingBlockNumber);
assertEq(oracle.STARTING_TIMESTAMP(), startingTimestamp);
assertEq(oracle.sequencer(), sequencer);
assertEq(oracle.owner(), owner);
L2OutputOracle.OutputProposal memory proposal = oracle.getL2Output(startingBlockNumber);
assertEq(proposal.outputRoot, genesisL2Output);
......@@ -39,7 +41,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
uint256 appendedNumber = oracle.nextBlockNumber();
// Roll to after the block number we'll append
oracleWarpRoll(appendedNumber);
warpToAppendTime(appendedNumber);
vm.prank(sequencer);
oracle.appendL2Output(appendedOutput1, appendedNumber, 0, 0);
assertEq(oracle.latestBlockNumber(), appendedNumber);
......@@ -48,7 +50,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
// Test: getL2Output() should return the correct value
function test_getL2Output() external {
uint256 nextBlockNumber = oracle.nextBlockNumber();
oracleWarpRoll(nextBlockNumber);
warpToAppendTime(nextBlockNumber);
vm.prank(sequencer);
oracle.appendL2Output(appendedOutput1, nextBlockNumber, 0, 0);
......@@ -72,7 +74,9 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
function test_computeL2Timestamp() external {
// reverts if timestamp is too low
vm.expectRevert("OutputOracle: Block number must be greater than or equal to the starting block number.");
vm.expectRevert(
"OutputOracle: Block number must be greater than or equal to the starting block number."
);
oracle.computeL2Timestamp(startingBlockNumber - 1);
// returns the correct value...
......@@ -80,10 +84,59 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
assertEq(oracle.computeL2Timestamp(startingBlockNumber), startingTimestamp);
// ... for the first block after the starting block
assertEq(oracle.computeL2Timestamp(startingBlockNumber + 1), startingTimestamp + submissionInterval);
assertEq(
oracle.computeL2Timestamp(startingBlockNumber + 1),
startingTimestamp + submissionInterval
);
// ... for some other block number
assertEq(oracle.computeL2Timestamp(startingBlockNumber + 96024), startingTimestamp + submissionInterval * 96024);
assertEq(
oracle.computeL2Timestamp(startingBlockNumber + 96024),
startingTimestamp + submissionInterval * 96024
);
}
/*******************
* Ownership tests *
*******************/
event SequencerChanged(address indexed previousSequencer, address indexed newSequencer);
function test_changeSequencer() public {
address newSequencer = address(20);
vm.expectRevert("Ownable: caller is not the owner");
oracle.changeSequencer(newSequencer);
vm.startPrank(owner);
vm.expectRevert("OutputOracle: new sequencer is the zero address");
oracle.changeSequencer(address(0));
vm.expectRevert("OutputOracle: sequencer cannot be same as the owner");
oracle.changeSequencer(owner);
// Double check sequencer has not changed.
assertEq(sequencer, oracle.sequencer());
vm.expectEmit(true, true, true, true);
emit SequencerChanged(sequencer, newSequencer);
oracle.changeSequencer(newSequencer);
vm.stopPrank();
}
event OwnershipTransferred(address indexed, address indexed);
function test_updateOwner() public {
address newOwner = address(21);
vm.expectRevert("Ownable: caller is not the owner");
oracle.transferOwnership(newOwner);
// Double check owner has not changed.
assertEq(owner, oracle.owner());
vm.startPrank(owner);
vm.expectEmit(true, true, true, true);
emit OwnershipTransferred(owner, newOwner);
oracle.transferOwnership(newOwner);
vm.stopPrank();
}
/*****************************
......@@ -95,7 +148,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
function test_appendingAnotherOutput() public {
bytes32 appendedOutput2 = keccak256(abi.encode(2));
uint256 nextBlockNumber = oracle.nextBlockNumber();
oracleWarpRoll(nextBlockNumber);
warpToAppendTime(nextBlockNumber);
uint256 appendedNumber = oracle.latestBlockNumber();
// Ensure the submissionInterval is enforced
......@@ -114,7 +167,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
bytes32 prevL1BlockHash = blockhash(prevL1BlockNumber);
uint256 nextBlockNumber = oracle.nextBlockNumber();
oracleWarpRoll(nextBlockNumber);
warpToAppendTime(nextBlockNumber);
vm.prank(sequencer);
oracle.appendL2Output(nonZeroHash, nextBlockNumber, prevL1BlockHash, prevL1BlockNumber);
}
......@@ -126,10 +179,10 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
// Test: appendL2Output fails if called by a party that is not the sequencer.
function testCannot_appendOutputIfNotSequencer() external {
uint256 nextBlockNumber = oracle.nextBlockNumber();
oracleWarpRoll(nextBlockNumber);
warpToAppendTime(nextBlockNumber);
vm.prank(address(128));
vm.expectRevert("Ownable: caller is not the owner");
vm.expectRevert("OutputOracle: caller is not the sequencer");
oracle.appendL2Output(nonZeroHash, nextBlockNumber, 0, 0);
}
......@@ -137,7 +190,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
function testCannot_appendEmptyOutput() external {
bytes32 outputToAppend = bytes32(0);
uint256 nextBlockNumber = oracle.nextBlockNumber();
oracleWarpRoll(nextBlockNumber);
warpToAppendTime(nextBlockNumber);
vm.prank(sequencer);
vm.expectRevert("OutputOracle: Cannot submit empty L2 output.");
oracle.appendL2Output(outputToAppend, nextBlockNumber, 0, 0);
......@@ -146,11 +199,12 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
// Test: appendL2Output fails if the block number doesn't match the next expected number.
function testCannot_appendUnexpectedBlockNumber() external {
uint256 nextBlockNumber = oracle.nextBlockNumber();
oracleWarpRoll(nextBlockNumber);
warpToAppendTime(nextBlockNumber);
vm.prank(sequencer);
vm.expectRevert("OutputOracle: Block number must be equal to next expected block number.");
oracle.appendL2Output(nonZeroHash, nextBlockNumber - 1, 0, 0);
}
// Test: appendL2Output fails if it would have a timestamp in the future.
function testCannot_appendFutureTimetamp() external {
uint256 nextBlockNumber = oracle.nextBlockNumber();
......@@ -165,7 +219,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
// protection.
function testCannot_appendOnWrongFork() external {
uint256 nextBlockNumber = oracle.nextBlockNumber();
oracleWarpRoll(nextBlockNumber);
warpToAppendTime(nextBlockNumber);
vm.prank(sequencer);
vm.expectRevert("OutputOracle: Blockhash does not match the hash at the expected height.");
oracle.appendL2Output(
......@@ -189,16 +243,16 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
bytes32 l1BlockHash = blockhash(l1BlockNumber);
uint256 nextBlockNumber = oracle.nextBlockNumber();
oracleWarpRoll(nextBlockNumber);
warpToAppendTime(nextBlockNumber);
vm.prank(sequencer);
// This will fail when foundry no longer returns zerod block hashes
oracle.appendL2Output(nonZeroHash, nextBlockNumber, l1BlockHash, l1BlockNumber - 1);
}
/****************
* Delete Tests *
****************/
/*****************************
* Delete Tests - Happy Path *
*****************************/
event L2OutputDeleted(
bytes32 indexed _l2Output,
......@@ -206,15 +260,18 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
uint256 indexed _l2BlockNumber
);
function test_deleteL2Output() external {
test_appendingAnotherOutput();
uint256 latestBlockNumber = oracle.latestBlockNumber();
L2OutputOracle.OutputProposal memory proposalToDelete = oracle.getL2Output(latestBlockNumber);
L2OutputOracle.OutputProposal memory newLatestOutput = oracle.getL2Output(latestBlockNumber - submissionInterval);
L2OutputOracle.OutputProposal memory proposalToDelete = oracle.getL2Output(
latestBlockNumber
);
L2OutputOracle.OutputProposal memory newLatestOutput = oracle.getL2Output(
latestBlockNumber - submissionInterval
);
vm.prank(sequencer);
vm.prank(owner);
vm.expectEmit(true, true, false, false);
emit L2OutputDeleted(
proposalToDelete.outputRoot,
......@@ -225,10 +282,7 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
// validate latestBlockNumber has been reduced
uint256 latestBlockNumberAfter = oracle.latestBlockNumber();
assertEq(
latestBlockNumber - submissionInterval,
latestBlockNumberAfter
);
assertEq(latestBlockNumber - submissionInterval, latestBlockNumberAfter);
L2OutputOracle.OutputProposal memory proposal = oracle.getL2Output(latestBlockNumberAfter);
// validate that the new latest output is as expected.
......@@ -236,7 +290,11 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
assertEq(newLatestOutput.timestamp, proposal.timestamp);
}
function testCannot_deleteL2Output_ifNotSequencer() external {
/***************************
* Delete Tests - Sad Path *
***************************/
function testCannot_deleteL2Output_ifNotOwner() external {
uint256 latestBlockNumber = oracle.latestBlockNumber();
L2OutputOracle.OutputProposal memory proposal = oracle.getL2Output(latestBlockNumber);
......@@ -244,14 +302,86 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
oracle.deleteL2Output(proposal);
}
function testCannot_deleteWrongL2Output() external {
function testCannot_deleteL2Output_withWrongRoot() external {
test_appendingAnotherOutput();
uint256 previousBlockNumber = oracle.latestBlockNumber() - submissionInterval;
L2OutputOracle.OutputProposal memory proposalToDelete = oracle.getL2Output(previousBlockNumber);
L2OutputOracle.OutputProposal memory proposalToDelete = oracle.getL2Output(
previousBlockNumber
);
vm.prank(sequencer);
vm.expectRevert("OutputOracle: The output root to delete does not match the latest output proposal.");
vm.prank(owner);
vm.expectRevert(
"OutputOracle: The output root to delete does not match the latest output proposal."
);
oracle.deleteL2Output(proposalToDelete);
}
function testCannot_deleteL2Output_withWrongTime() external {
test_appendingAnotherOutput();
uint256 latestBlockNumber = oracle.latestBlockNumber();
L2OutputOracle.OutputProposal memory proposalToDelete = oracle.getL2Output(
latestBlockNumber
);
// Modify the timestamp so that it does not match.
proposalToDelete.timestamp -= 1;
vm.prank(owner);
vm.expectRevert(
"OutputOracle: The timestamp to delete does not match the latest output proposal."
);
oracle.deleteL2Output(proposalToDelete);
}
}
contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {
L2OutputOracle oracleImpl;
Proxy internal proxy;
uint64 initialBlockNum;
function setUp() override public {
super.setUp();
initialBlockNum = uint64(block.number);
// Rename the deployed oracle instance for the purposes of this test.
oracleImpl = oracle;
proxy = new Proxy(alice);
vm.prank(alice);
proxy.upgradeToAndCall(
address(oracleImpl),
abi.encodeWithSelector(
L2OutputOracle.initialize.selector,
genesisL2Output,
startingBlockNumber,
sequencer,
owner
)
);
}
function test_initValuesOnProxy() external {
assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL());
assertEq(historicalTotalBlocks, oracleImpl.HISTORICAL_TOTAL_BLOCKS());
assertEq(startingBlockNumber, oracleImpl.STARTING_BLOCK_NUMBER());
assertEq(startingTimestamp, oracleImpl.STARTING_TIMESTAMP());
assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME());
L2OutputOracle.OutputProposal memory initOutput = oracleImpl.getL2Output(startingBlockNumber);
assertEq(genesisL2Output, initOutput.outputRoot);
assertEq(initL1Time, initOutput.timestamp);
assertEq(sequencer, oracleImpl.sequencer());
assertEq(owner, oracleImpl.owner());
}
function test_cannotInitProxy() external {
vm.expectRevert("Initializable: contract is already initialized");
address(proxy).call(abi.encodeWithSelector(L2OutputOracle.initialize.selector));
}
function test_cannotInitImpl() external {
vm.expectRevert("Initializable: contract is already initialized");
address(oracleImpl).call(abi.encodeWithSelector(L2OutputOracle.initialize.selector));
}
}
......@@ -19,8 +19,7 @@ contract OptimismPortal_Test is L2OutputOracle_Initializer {
bytes data
);
// Dependencies
// L2OutputOracle oracle;
// Test target
OptimismPortal op;
function setUp() public override {
......
import { ethers } from 'ethers'
const { env } = process
const startingTimestamp =
typeof env.L2OO_STARTING_BLOCK_TIMESTAMP === 'string'
? ethers.BigNumber.from(env.L2OO_STARTING_BLOCK_TIMESTAMP).toNumber()
: Date.now() / 1000
const config = {
submissionInterval: 6,
l2BlockTime: 2,
genesisOutput: ethers.constants.HashZero,
historicalBlocks: 0,
startingBlockTimestamp:
parseInt(process.env.L2OO_STARTING_BLOCK_TIMESTAMP, 10) || Date.now(),
startingBlockNumber: 0,
l2BlockTime: 2,
startingTimestamp,
sequencerAddress: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
l2CrossDomainMessengerOwner: ethers.constants.AddressZero,
gasPriceOracleOwner: ethers.constants.AddressZero,
gasPriceOracleOverhead: 2100,
gasPriceOracleScalar: 1000000,
gasPriceOracleDecimals: 6,
l1BlockInitialNumber: 0,
l1BlockInitialTimestamp: 0,
l1BlockInitialBasefee: 10,
l1BlockInitialHash: ethers.constants.HashZero,
l1BlockInitialSequenceNumber: 0,
proxyAdmin: '0x829BD824B016326A401d083B33D092293333A830',
genesisBlockExtradata: ethers.utils.hexConcat([
ethers.constants.HashZero,
'0xca062b0fd91172d89bcd4bb084ac4e21972cc467',
ethers.utils.hexZeroPad('0x', 65),
]),
genesisBlockGasLimit: ethers.BigNumber.from(15000000).toHexString(),
genesisBlockChainid: 901,
fundDevAccounts: true,
optimsismBaseFeeRecipient: '0xBcd4042DE499D14e55001CcbB24a551F3b954096',
optimismL1FeeRecipient: '0x71bE63f3384f5fb98995898A86B02Fb2426c5788',
deploymentWaitConfirmations: 1,
maxSequencerDrift: 10,
sequencerWindowSize: 2,
ownerAddress: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
}
export default config
......@@ -5,7 +5,7 @@ const config = {
l2BlockTime: 2,
genesisOutput: ethers.constants.HashZero,
historicalBlocks: 0,
startingBlockTimestamp: 1652907966,
startingTimestamp: 1652907966,
sequencerAddress: '0x7431310e026B69BFC676C0013E12A1A11411EEc9',
}
......
import { ethers } from 'ethers'
const { env } = process
const startingTimestamp =
typeof env.L2OO_STARTING_BLOCK_TIMESTAMP === 'string'
? ethers.BigNumber.from(env.L2OO_STARTING_BLOCK_TIMESTAMP).toNumber()
: Date.now() / 1000
const config = {
submissionInterval: 6,
l2BlockTime: 2,
genesisOutput: ethers.constants.HashZero,
historicalBlocks: 0,
startingBlockTimestamp:
parseInt(process.env.L2OO_STARTING_BLOCK_TIMESTAMP, 10) || Date.now(),
startingBlockNumber: 0,
l2BlockTime: 2,
startingTimestamp,
sequencerAddress: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
maxSequencerDrift: 10,
sequencerWindowSize: 2,
ownerAddress: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
}
export default config
/* Imports: Internal */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { BigNumber } from 'ethers'
import 'hardhat-deploy'
import '@nomiclabs/hardhat-ethers'
import '@eth-optimism/hardhat-deploy-config'
const deployFn: DeployFunction = async (hre) => {
const { deploy } = hre.deployments
const { deployer } = await hre.getNamedAccounts()
const { deployConfig } = hre
if (
typeof hre.deployConfig.startingBlockTimestamp !== 'number' ||
isNaN(hre.deployConfig.startingBlockTimestamp)
typeof deployConfig.startingTimestamp !== 'number' ||
isNaN(deployConfig.startingTimestamp)
) {
throw new Error(
'Cannot deploy L2OutputOracle without specifying a valid startingBlockTimestamp.'
'Cannot deploy L2OutputOracle without specifying a valid startingTimestamp.'
)
}
await deploy('L2OutputOracleProxy', {
contract: 'Proxy',
from: deployer,
args: [deployer],
log: true,
waitConfirmations: deployConfig.deploymentWaitConfirmations,
})
await deploy('L2OutputOracle', {
from: deployer,
args: [
hre.deployConfig.submissionInterval,
hre.deployConfig.l2BlockTime,
hre.deployConfig.genesisOutput,
hre.deployConfig.historicalBlocks,
hre.deployConfig.startingBlockTimestamp,
hre.deployConfig.sequencerAddress,
deployConfig.submissionInterval,
deployConfig.genesisOutput,
deployConfig.historicalBlocks,
deployConfig.startingBlockNumber,
deployConfig.startingTimestamp,
deployConfig.l2BlockTime,
deployConfig.sequencerAddress,
deployConfig.ownerAddress,
],
log: true,
waitConfirmations: 1,
waitConfirmations: deployConfig.deploymentWaitConfirmations,
})
const oracle = await hre.deployments.get('L2OutputOracle')
const proxy = await hre.deployments.get('L2OutputOracleProxy')
const Proxy = await hre.ethers.getContractAt('Proxy', proxy.address)
const L2OutputOracle = await hre.ethers.getContractAt(
'L2OutputOracle',
proxy.address
)
const tx = await Proxy.upgradeToAndCall(
oracle.address,
L2OutputOracle.interface.encodeFunctionData(
'initialize(bytes32,uint256,address,address)',
[
deployConfig.genesisOutput,
deployConfig.startingBlockNumber,
deployConfig.sequencerAddress,
deployConfig.ownerAddress,
]
)
)
await tx.wait()
const submissionInterval = await L2OutputOracle.SUBMISSION_INTERVAL()
if (!submissionInterval.eq(BigNumber.from(deployConfig.submissionInterval))) {
throw new Error('submission internal misconfigured')
}
const historicalBlocks = await L2OutputOracle.HISTORICAL_TOTAL_BLOCKS()
if (!historicalBlocks.eq(BigNumber.from(deployConfig.historicalBlocks))) {
throw new Error('historal total blocks misconfigured')
}
const startingBlockNumber = await L2OutputOracle.STARTING_BLOCK_NUMBER()
if (
!startingBlockNumber.eq(BigNumber.from(deployConfig.startingBlockNumber))
) {
throw new Error('starting block number misconfigured')
}
const startingTimestamp = await L2OutputOracle.STARTING_TIMESTAMP()
if (!startingTimestamp.eq(BigNumber.from(deployConfig.startingTimestamp))) {
throw new Error('starting timestamp misconfigured')
}
const l2BlockTime = await L2OutputOracle.L2_BLOCK_TIME()
if (!l2BlockTime.eq(BigNumber.from(deployConfig.l2BlockTime))) {
throw new Error('L2 block time misconfigured')
}
}
deployFn.tags = ['L2OutputOracle']
......
/* Imports: Internal */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import 'hardhat-deploy'
import '@nomiclabs/hardhat-ethers'
import '@eth-optimism/hardhat-deploy-config'
const deployFn: DeployFunction = async (hre) => {
const { deploy, get } = hre.deployments
const { deployer } = await hre.getNamedAccounts()
const { deployConfig } = hre
await deploy('OptimismPortalProxy', {
contract: 'Proxy',
from: deployer,
args: [deployer],
log: true,
waitConfirmations: deployConfig.deploymentWaitConfirmations,
})
const oracle = await get('L2OutputOracle')
await deploy('OptimismPortal', {
from: deployer,
args: [oracle.address, 2],
log: true,
waitConfirmations: 1,
waitConfirmations: deployConfig.deploymentWaitConfirmations,
})
const proxy = await hre.deployments.get('OptimismPortalProxy')
const Proxy = await hre.ethers.getContractAt('Proxy', proxy.address)
const portal = await hre.deployments.get('OptimismPortal')
const tx = await Proxy.upgradeTo(portal.address)
await tx.wait()
const OptimismPortal = await hre.ethers.getContractAt(
'OptimismPortal',
proxy.address
)
const l2Oracle = await OptimismPortal.L2_ORACLE()
if (l2Oracle !== oracle.address) {
throw new Error('L2 Oracle mismatch')
}
}
deployFn.tags = ['OptimismPortal']
......
/* Imports: Internal */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { Contract } from 'ethers'
import 'hardhat-deploy'
import '@nomiclabs/hardhat-ethers'
import '@eth-optimism/hardhat-deploy-config'
const deployFn: DeployFunction = async (hre) => {
const { deploy } = hre.deployments
const { deployer } = await hre.getNamedAccounts()
const { deployConfig } = hre
await deploy('L1CrossDomainMessengerProxy', {
contract: 'Proxy',
from: deployer,
args: [deployer],
log: true,
waitConfirmations: deployConfig.deploymentWaitConfirmations,
})
await deploy('L1CrossDomainMessenger', {
from: deployer,
args: [],
log: true,
waitConfirmations: 1,
waitConfirmations: deployConfig.deploymentWaitConfirmations,
})
const provider = hre.ethers.provider.getSigner(deployer)
const oracle = await hre.deployments.get('L2OutputOracle')
const proxy = await hre.deployments.get('L1CrossDomainMessengerProxy')
const Proxy = await hre.ethers.getContractAt('Proxy', proxy.address)
const messenger = await hre.deployments.get('L1CrossDomainMessenger')
const portal = await hre.deployments.get('OptimismPortal')
const L1CrossDomainMessenger = await hre.ethers.getContractAt(
'L1CrossDomainMessenger',
proxy.address
)
const L1CrossDomainMessenger = new Contract(
const upgradeTx = await Proxy.upgradeToAndCall(
messenger.address,
messenger.abi,
provider
L1CrossDomainMessenger.interface.encodeFunctionData('initialize(address)', [
portal.address,
])
)
await upgradeTx.wait()
const tx = await L1CrossDomainMessenger.initialize(oracle.address)
const receipt = await tx.wait()
console.log(`${receipt.transactionHash}: initialize(${oracle.address})`)
const portalAddress = await L1CrossDomainMessenger.portal()
if (portalAddress !== portal.address) {
throw new Error('portal misconfigured')
}
}
deployFn.tags = ['L1CrossDomainMessenger']
......
/* Imports: Internal */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { Contract } from 'ethers'
import 'hardhat-deploy'
import '@nomiclabs/hardhat-ethers'
import '@eth-optimism/hardhat-deploy-config'
const deployFn: DeployFunction = async (hre) => {
const { deploy } = hre.deployments
const { deployer } = await hre.getNamedAccounts()
const { deployConfig } = hre
await deploy('L1StandardBridgeProxy', {
contract: 'Proxy',
from: deployer,
args: [deployer],
log: true,
waitConfirmations: deployConfig.deploymentWaitConfirmations,
})
await deploy('L1StandardBridge', {
from: deployer,
args: [],
log: true,
waitConfirmations: 1,
waitConfirmations: deployConfig.deploymentWaitConfirmations,
})
const provider = hre.ethers.provider.getSigner(deployer)
const messenger = await hre.deployments.get('L1CrossDomainMessenger')
const proxy = await hre.deployments.get('L1StandardBridgeProxy')
const Proxy = await hre.ethers.getContractAt('Proxy', proxy.address)
const bridge = await hre.deployments.get('L1StandardBridge')
const L1StandardBridge = new Contract(bridge.address, bridge.abi, provider)
const tx = await L1StandardBridge.initialize(messenger.address)
const receipt = await tx.wait()
console.log(`${receipt.transactionHash}: initialize(${messenger.address})`)
const messenger = await hre.deployments.get('L1CrossDomainMessengerProxy')
const L1StandardBridge = await hre.ethers.getContractAt(
'L1StandardBridge',
proxy.address
)
const upgradeTx = await Proxy.upgradeToAndCall(
bridge.address,
L1StandardBridge.interface.encodeFunctionData('initialize(address)', [
messenger.address,
])
)
await upgradeTx.wait()
if (messenger.address !== (await L1StandardBridge.messenger())) {
throw new Error('misconfigured messenger')
}
}
deployFn.tags = ['L1StandardBridge']
......
/* Imports: Internal */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { Contract } from 'ethers'
import 'hardhat-deploy'
import '@nomiclabs/hardhat-ethers'
import '@eth-optimism/hardhat-deploy-config'
const deployFn: DeployFunction = async (hre) => {
const { deploy } = hre.deployments
const { deployer } = await hre.getNamedAccounts()
const { deployConfig } = hre
await deploy('OptimismMintableTokenFactoryProxy', {
contract: 'Proxy',
from: deployer,
args: [deployer],
log: true,
waitConfirmations: deployConfig.deploymentWaitConfirmations,
})
await deploy('OptimismMintableTokenFactory', {
from: deployer,
args: [],
log: true,
waitConfirmations: 1,
waitConfirmations: deployConfig.deploymentWaitConfirmations,
})
const provider = hre.ethers.provider.getSigner(deployer)
const factory = await hre.deployments.get('OptimismMintableTokenFactory')
const bridge = await hre.deployments.get('L1StandardBridge')
const bridge = await hre.deployments.get('L1StandardBridgeProxy')
const proxy = await hre.deployments.get('OptimismMintableTokenFactoryProxy')
const Proxy = await hre.ethers.getContractAt('Proxy', proxy.address)
const OptimismMintableTokenFactory = await hre.ethers.getContractAt(
'OptimismMintableTokenFactory',
proxy.address
)
const OptimismMintableTokenFactory = new Contract(
const upgradeTx = await Proxy.upgradeToAndCall(
factory.address,
factory.abi,
provider
OptimismMintableTokenFactory.interface.encodeFunctionData(
'initialize(address)',
[bridge.address]
)
)
await upgradeTx.wait()
const tx = await OptimismMintableTokenFactory.initialize(bridge.address)
const receipt = await tx.wait()
console.log(`${receipt.transactionHash}: initialize(${bridge.address})`)
if (bridge.address !== (await OptimismMintableTokenFactory.bridge())) {
throw new Error('bridge misconfigured')
}
}
deployFn.tags = ['OptimismMintableTokenFactory']
......
......@@ -13,4 +13,6 @@ remappings = [
'ds-test/=node_modules/ds-test/src'
]
extra_output = ['devdoc', 'userdoc', 'metadata', 'storageLayout']
bytecode_hash = "none"
bytecode_hash = 'none'
# build_info = true
......@@ -3,7 +3,7 @@ import { HardhatUserConfig, task, subtask } from 'hardhat/config'
import { TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS } from 'hardhat/builtin-tasks/task-names'
// Hardhat plugins
import '@nomiclabs/hardhat-waffle'
import '@nomiclabs/hardhat-ethers'
import '@typechain/hardhat'
import 'solidity-coverage'
import 'hardhat-deploy'
......@@ -11,7 +11,10 @@ import '@foundry-rs/hardhat-forge'
import '@eth-optimism/hardhat-deploy-config'
// Hardhat tasks
import './tasks/genesis-l1'
import './tasks/genesis-l2'
import './tasks/deposits'
import './tasks/rollup-config'
subtask(TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS).setAction(
async (_, __, runSuper) => {
......@@ -39,10 +42,8 @@ const config: HardhatUserConfig = {
},
goerli: {
chainId: 5,
url: (process.env.L1_RPC || ''),
accounts: [
(process.env.PRIVATE_KEY_DEPLOYER || ethers.constants.HashZero),
],
url: process.env.L1_RPC || '',
accounts: [process.env.PRIVATE_KEY_DEPLOYER || ethers.constants.HashZero],
},
},
paths: {
......@@ -73,12 +74,31 @@ const config: HardhatUserConfig = {
historicalBlocks: {
type: 'number',
},
startingBlockTimestamp: {
startingBlockNumber: {
type: 'number',
},
startingTimestamp: {
type: 'number',
},
sequencerAddress: {
type: 'address',
},
ownerAddress: {
type: 'address',
},
},
external: {
contracts: [
{
artifacts: '../contracts/artifacts',
},
{
artifacts: '../contracts-governance/artifacts',
},
],
deployments: {
goerli: ['../contracts/deployments/goerli'],
},
},
solidity: {
compilers: [
......
......@@ -20,9 +20,10 @@
"build:ts": "tsc",
"test": "forge test",
"gas-snapshot": "forge snapshot",
"storage-snapshot": "./scripts/storage-snapshot.sh",
"slither": "slither .",
"clean": "rm -rf ./dist ./artifacts ./forge-artifacts ./cache ./coverage ./tsconfig.tsbuildinfo",
"lint:ts:check": "eslint .",
"lint:ts:check": "eslint . --max-warnings=0",
"lint:contracts:check": "yarn solhint -f table 'contracts/**/*.sol'",
"lint:check": "yarn lint:contracts:check && yarn lint:ts:check",
"lint:ts:fix": "yarn prettier --write .",
......@@ -44,6 +45,7 @@
},
"devDependencies": {
"@eth-optimism/hardhat-deploy-config": "^0.2.0",
"@defi-wonderland/smock": "^2.0.2",
"@foundry-rs/hardhat-forge": "^0.1.7",
"@nomiclabs/hardhat-ethers": "^2.0.0",
"@nomiclabs/hardhat-waffle": "^2.0.0",
......
#!/usr/bin/env bash
set -e
if ! command -v forge &> /dev/null
then
echo "forge could not be found. Please install forge by running:"
echo "curl -L https://foundry.paradigm.xyz | bash"
exit
fi
contracts=(
L1CrossDomainMessenger
L1StandardBridge
L2OutputOracle
OptimismPortal
DeployerWhitelist
GasPriceOracle
L1Block
L1BlockNumber
L2CrossDomainMessenger
L2StandardBridge
L2ToL1MessagePasser
OVM_ETH
SequencerFeeVault
WETH9
ProxyAdmin
Proxy
L1ChugSplashProxy
OptimismMintableERC20
OptimismMintableTokenFactory
)
dir=$(dirname "$0")
echo "Creating storage layout diagrams.."
echo "=======================" > $dir/../.storage-layout
echo "👁👁 STORAGE LAYOUT snapshot 👁👁" >> $dir/../.storage-layout
echo "=======================" >> $dir/../.storage-layout
for contract in ${contracts[@]}
do
echo -e "\n=======================" >> $dir/../.storage-layout
echo "➡ $contract">> $dir/../.storage-layout
echo -e "=======================\n" >> $dir/../.storage-layout
forge inspect --pretty $contract storage-layout >> $dir/../.storage-layout
done
echo "Storage layout snapshot stored at $dir/../.storage-layout"
/**
* Predeploys are Solidity contracts that are injected into the initial L2 state and provide
* various useful functions.
* Notes:
* 0x42...04 was the address of the OVM_ProxySequencerEntrypoint. This contract is no longer in
* use and has therefore been removed. We may place a new predeployed contract at this address
* in the future. See https://github.com/ethereum-optimism/optimism/pull/549 for more info.
*/
export const bedrockPredeploys = {
L1_BLOCK_ATTRIBUTES: '0x4200000000000000000000000000000000000015',
WITHDRAWER: '0x4200000000000000000000000000000000000016',
export const predeploys = {
L2ToL1MessagePasser: '0x4200000000000000000000000000000000000000',
DeployerWhitelist: '0x4200000000000000000000000000000000000002',
L2CrossDomainMessenger: '0x4200000000000000000000000000000000000007',
GasPriceOracle: '0x420000000000000000000000000000000000000F',
L2StandardBridge: '0x4200000000000000000000000000000000000010',
SequencerFeeVault: '0x4200000000000000000000000000000000000011',
OptimismMintableTokenFactory: '0x4200000000000000000000000000000000000012',
L1BlockNumber: '0x4200000000000000000000000000000000000013',
L1Block: '0x4200000000000000000000000000000000000015',
OVM_ETH: '0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000',
WETH9: '0x4200000000000000000000000000000000000006',
GovernanceToken: '0x4200000000000000000000000000000000000042',
}
export const futurePredeploys = {
System1: '0x4200000000000000000000000000000000000014',
}
......@@ -2,7 +2,7 @@ import { ethers } from 'ethers'
import { toHexString } from '@eth-optimism/core-utils'
import { TrieTestGenerator } from './trie-test-generator'
import { bedrockPredeploys } from './constants'
import { predeploys } from './constants'
interface WithdrawalArgs {
nonce: number
......@@ -63,7 +63,7 @@ export const generateMockWithdrawalProof = async (
const generator = await TrieTestGenerator.fromAccounts({
accounts: [
{
address: bedrockPredeploys.WITHDRAWER,
address: predeploys.L2ToL1MessagePasser,
nonce: 0,
balance: 0,
codeHash: ethers.utils.keccak256('0x1234'),
......
import fs from 'fs'
import { ethers } from 'ethers'
import { task } from 'hardhat/config'
import { Genesis, State } from '@eth-optimism/core-utils'
task('genesis-l1', 'create a genesis config')
.addOptionalParam(
'outfile',
'The file to write the output JSON to',
'genesis.json'
)
.setAction(async (args, hre) => {
// TODO: type needs to be updated to work with modern geth
const alloc: State | any = {}
// Give each predeploy a single wei
for (let i = 0; i <= 0xff; i++) {
const buf = Buffer.alloc(2)
buf.writeUInt16BE(i, 0)
const addr = ethers.utils.hexConcat([
'0x000000000000000000000000000000000000',
ethers.utils.hexZeroPad(buf, 2),
])
alloc[addr] = {
balance: '0x1',
}
}
// Prefund dev accounts
const accounts = [
'0x14dC79964da2C08b23698B3D3cc7Ca32193d9955',
'0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65',
'0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec',
'0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f',
'0x2546BcD3c84621e976D8185a91A922aE77ECEc30',
'0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
'0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
'0x71bE63f3384f5fb98995898A86B02Fb2426c5788',
'0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199',
'0x90F79bf6EB2c4f870365E785982E1f101E93b906',
'0x976EA74026E726554dB657fA54763abd0C3a0aa9',
'0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc',
'0xBcd4042DE499D14e55001CcbB24a551F3b954096',
'0xFABB0ac9d68B0B445fB7357272Ff202C5651694a',
'0xa0Ee7A142d267C1f36714E4a8F75612F20a79720',
'0xbDA5747bFD65F08deb54cb465eB87D40e51B197E',
'0xcd3B766CCDd6AE721141F452C550Ca635964ce71',
'0xdD2FD4581271e230360230F9337D5c0430Bf44C0',
'0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097',
'0xde3829a23df1479438622a08a116e8eb3f620bb5',
'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
]
const signers = await hre.ethers.getSigners()
for (const signer of signers) {
accounts.push(signer.address)
}
for (const account of accounts) {
alloc[ethers.utils.getAddress(account)] = {
balance:
'0x200000000000000000000000000000000000000000000000000000000000000',
}
}
const timestamp = hre.deployConfig.startingTimestamp
if (timestamp === undefined) {
throw new Error('Must configure starting block timestamp')
}
const genesis: Genesis = {
config: {
chainId: 900,
homesteadBlock: 0,
eip150Block: 0,
eip150Hash:
'0x0000000000000000000000000000000000000000000000000000000000000000',
eip155Block: 0,
eip158Block: 0,
byzantiumBlock: 0,
constantinopleBlock: 0,
petersburgBlock: 0,
istanbulBlock: 0,
muirGlacierBlock: 0,
berlinBlock: 0,
londonBlock: 0,
clique: {
period: 15,
epoch: 30000,
},
},
nonce: '0x0',
timestamp: ethers.BigNumber.from(timestamp).toHexString(),
extraData:
'0x0000000000000000000000000000000000000000000000000000000000000000ca062b0fd91172d89bcd4bb084ac4e21972cc4670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
gasLimit: ethers.BigNumber.from(15_000_000).toHexString(),
difficulty: '0x1',
mixHash:
'0x0000000000000000000000000000000000000000000000000000000000000000',
coinbase: '0x0000000000000000000000000000000000000000',
alloc,
}
fs.writeFileSync(args.outfile, JSON.stringify(genesis, null, 2))
})
import fs from 'fs'
import assert from 'assert'
import { OptimismGenesis, State } from '@eth-optimism/core-utils'
import { ethers } from 'ethers'
import { task } from 'hardhat/config'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import { predeploys } from '../src'
const prefix = '0x420000000000000000000000000000000000'
const implementationSlot =
'0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc'
const adminSlot =
'0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103'
const toCodeAddr = (addr: string) => {
const address = ethers.utils.hexConcat([
'0xc0d3c0d3c03dc03dc03dc03dc03dc03dc03d',
'0x' + addr.slice(prefix.length),
])
return ethers.utils.getAddress(address)
}
const assertEvenLength = (str: string) => {
assert(str.length % 2 === 0, str)
}
// TODO: this can be replaced with the smock version after
// a new release of foundry-rs/hardhat
const getStorageLayout = async (
hre: HardhatRuntimeEnvironment,
name: string
) => {
const buildInfo = await hre.artifacts.getBuildInfo(name)
const key = Object.keys(buildInfo.output.contracts)[0]
return (buildInfo.output.contracts[key][name] as any).storageLayout
}
task('genesis-l2', 'create a genesis config')
.addOptionalParam(
'outfile',
'The file to write the output JSON to',
'genesis.json'
)
.setAction(async (args, hre) => {
const {
computeStorageSlots,
// eslint-disable-next-line @typescript-eslint/no-var-requires
} = require('@defi-wonderland/smock/dist/src/utils')
const { deployConfig } = hre
// Use the addresses of the proxies here instead of the implementations
// Be backwards compatible
let ProxyL1CrossDomainMessenger = await hre.deployments.getOrNull(
'Proxy__OVM_L1CrossDomainMessenger'
)
if (ProxyL1CrossDomainMessenger === undefined) {
ProxyL1CrossDomainMessenger = await hre.deployments.get(
'L1CrossDomainMessengerProxy'
)
}
// Be backwards compatible
let ProxyL1StandardBridge = await hre.deployments.getOrNull(
'Proxy__OVM_L1StandardBridge'
)
if (ProxyL1StandardBridge === undefined) {
ProxyL1StandardBridge = await hre.deployments.get('L1StandardBridgeProxy')
}
const variables = {
L2ToL1MessagePasser: {
nonce: 0,
},
L2CrossDomainMessenger: {
_initialized: 1,
_owner: deployConfig.l2CrossDomainMessengerOwner,
xDomainMsgSender: '0x000000000000000000000000000000000000dEaD',
msgNonce: 0,
otherMessenger: ProxyL1CrossDomainMessenger.address,
// TODO: handle blockedSystemAddresses mapping
// blockedSystemAddresses: [{key: '', value: ''}],
},
GasPriceOracle: {
_owner: deployConfig.gasPriceOracleOwner,
overhead: deployConfig.gasPriceOracleOverhead,
scalar: deployConfig.gasPriceOracleScalar,
decimals: deployConfig.gasPriceOracleDecimals,
},
L2StandardBridge: {
messenger: predeploys.L2CrossDomainMessenger,
otherBridge: ProxyL1StandardBridge.address,
},
SequencerFeeVault: {
l1FeeWallet: ethers.constants.AddressZero,
},
OptimismMintableTokenFactory: {
bridge: ethers.constants.AddressZero,
},
L1Block: {
number: deployConfig.l1BlockInitialNumber,
timestamp: deployConfig.l1BlockInitialTimestamp,
basefee: deployConfig.l1BlockInitialBasefee,
hash: deployConfig.l1BlockInitialHash,
sequenceNumber: deployConfig.l1BlockInitialSequenceNumber,
},
OVM_ETH: {
bridge: predeploys.L2StandardBridge,
remoteToken: ethers.constants.AddressZero,
_name: 'Ether',
_symbol: 'ETH',
},
WETH9: {
name: 'Wrapped Ether',
symbol: 'WETH',
decimals: 18,
},
GovernanceToken: {
name: 'Optimism',
symbol: 'OP',
_owner: deployConfig.proxyAdmin,
},
}
assertEvenLength(implementationSlot)
assertEvenLength(adminSlot)
assertEvenLength(deployConfig.proxyAdmin)
const predeployAddrs = new Set()
for (const addr of Object.values(predeploys)) {
predeployAddrs.add(ethers.utils.getAddress(addr))
}
// TODO: geth likes strings for nonce and balance now
const alloc: State = {}
// Set a proxy at each predeploy address
const proxy = await hre.artifacts.readArtifact('Proxy')
for (let i = 0; i <= 0xffff; i++) {
const num = ethers.utils.hexZeroPad('0x' + i.toString(16), 2)
const addr = ethers.utils.getAddress(
ethers.utils.hexConcat([prefix, num])
)
// There is no proxy at OVM_ETH or the GovernanceToken
if (
addr === ethers.utils.getAddress(predeploys.OVM_ETH) ||
addr === ethers.utils.getAddress(predeploys.GovernanceToken)
) {
continue
}
alloc[addr] = {
nonce: '0x0',
balance: '0x0',
code: proxy.deployedBytecode,
storage: {
[adminSlot]: deployConfig.proxyAdmin,
},
}
if (predeployAddrs.has(ethers.utils.getAddress(addr))) {
alloc[addr].storage[implementationSlot] = toCodeAddr(addr)
}
}
// Set the GovernanceToken in the state
// Cannot easily set storage due to no easy access to compiler
// output
const governanceToken = await hre.deployments.getArtifact('GovernanceToken')
alloc[predeploys.GovernanceToken] = {
nonce: '0x0',
balance: '0x0',
code: governanceToken.deployedBytecode,
}
// Give each predeploy a single wei
for (let i = 0; i <= 0xff; i++) {
const buf = Buffer.alloc(2)
buf.writeUInt16BE(i, 0)
const addr = ethers.utils.hexConcat([
'0x000000000000000000000000000000000000',
ethers.utils.hexZeroPad(buf, 2),
])
alloc[addr] = {
balance: '0x1',
}
}
if (deployConfig.fundDevAccounts) {
const accounts = [
'0xde3829a23df1479438622a08a116e8eb3f620bb5',
'0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
'0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
'0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
]
const signers = await hre.ethers.getSigners()
for (const signer of signers) {
accounts.push(signer.address)
}
for (const account of accounts) {
alloc[account] = {
balance:
'0x200000000000000000000000000000000000000000000000000000000000000',
}
}
}
// Set the predeploys in the state
for (const [name, addr] of Object.entries(predeploys)) {
if (name === 'GovernanceToken') {
continue
}
const artifact = await hre.artifacts.readArtifact(name)
assertEvenLength(artifact.deployedBytecode)
const allocAddr = name === 'OVM_ETH' ? addr : toCodeAddr(addr)
assertEvenLength(allocAddr)
alloc[allocAddr] = {
nonce: '0x00',
balance: '0x00',
code: artifact.deployedBytecode,
storage: {},
}
const storageLayout = await getStorageLayout(hre, name)
const slots = computeStorageSlots(storageLayout, variables[name])
for (const slot of slots) {
alloc[allocAddr].storage[slot.key] = slot.val
}
}
const genesis: OptimismGenesis = {
config: {
chainId: deployConfig.genesisBlockChainid,
homesteadBlock: 0,
eip150Block: 0,
eip155Block: 0,
eip158Block: 0,
byzantiumBlock: 0,
constantinopleBlock: 0,
petersburgBlock: 0,
istanbulBlock: 0,
muirGlacierBlock: 0,
berlinBlock: 0,
londonBlock: 0,
mergeForkBlock: 0,
terminalTotalDifficulty: 0,
clique: {
period: 0,
epoch: 30000,
},
},
nonce: '0x1234',
difficulty: '0x1',
timestamp: ethers.BigNumber.from(
deployConfig.startingTimestamp
).toHexString(),
gasLimit: deployConfig.genesisBlockGasLimit,
extraData: deployConfig.genesisBlockExtradata,
optimism: {
enabled: true,
baseFeeRecipient: deployConfig.optimsismBaseFeeRecipient,
l1FeeRecipient: deployConfig.optimismL1FeeRecipient,
},
alloc,
}
fs.writeFileSync(args.outfile, JSON.stringify(genesis, null, 2))
})
import fs from 'fs'
import { task } from 'hardhat/config'
import { OpNodeConfig, getChainId } from '@eth-optimism/core-utils'
import { ethers } from 'ethers'
task('rollup-config', 'create a genesis config')
.addOptionalParam(
'outfile',
'The file to write the output JSON to',
'rollup.json'
)
.addOptionalParam('l1RpcUrl', 'The L1 RPC URL', 'http://127.0.0.1:8545')
.addOptionalParam('l2RpcUrl', 'The L2 RPC URL', 'http://127.0.0.1:9545')
.setAction(async (args, hre) => {
const { deployConfig } = hre
const l1 = new ethers.providers.StaticJsonRpcProvider(args.l1RpcUrl)
const l2 = new ethers.providers.StaticJsonRpcProvider(args.l2RpcUrl)
const l1Genesis = await l1.getBlock('earliest')
const l2Genesis = await l2.getBlock('earliest')
const portal = await hre.deployments.get('OptimismPortalProxy')
const config: OpNodeConfig = {
genesis: {
l1: {
hash: l1Genesis.hash,
number: 0,
},
l2: {
hash: l2Genesis.hash,
number: 0,
},
l2_time: deployConfig.startingTimestamp,
},
block_time: deployConfig.l2BlockTime,
max_sequencer_drift: deployConfig.maxSequencerDrift,
seq_window_size: deployConfig.sequencerWindowSize,
l1_chain_id: await getChainId(l1),
l2_chain_id: await getChainId(l2),
p2p_sequencer_address: '0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc',
fee_recipient_address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
batch_inbox_address: '0xff00000000000000000000000000000000000002',
batch_sender_address: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
deposit_contract_address: portal.address,
}
fs.writeFileSync(args.outfile, JSON.stringify(config, null, 2))
})
......@@ -7,6 +7,7 @@ import 'solidity-coverage'
import { task, types } from 'hardhat/config'
import { providers, utils, Wallet } from 'ethers'
import { CrossChainMessenger } from '@eth-optimism/sdk'
import { getChainId } from '@eth-optimism/core-utils'
import './scripts/deploy-token'
import './scripts/multi-send'
......@@ -42,11 +43,13 @@ task('deposit', 'Deposits funds onto Optimism.')
}
const l1Provider = new providers.JsonRpcProvider(l1ProviderUrl)
const l2Provider = new providers.JsonRpcProvider(l2ProviderUrl)
const l1Wallet = new Wallet(privateKey, l1Provider)
const messenger = new CrossChainMessenger({
l1SignerOrProvider: l1Wallet,
l2SignerOrProvider: l2ProviderUrl,
l1ChainId: (await l1Provider.getNetwork()).chainId,
l2SignerOrProvider: l2Provider,
l1ChainId: await getChainId(l1Provider),
l2ChainId: await getChainId(l2Provider),
})
const amountWei = utils.parseEther(amountEth)
......@@ -57,8 +60,6 @@ task('deposit', 'Deposits funds onto Optimism.')
console.log(`Got TX hash ${tx.hash}. Waiting...`)
await tx.wait()
const l2Provider = new providers.JsonRpcProvider(l2ProviderUrl)
const l1WalletOnL2 = new Wallet(privateKey, l2Provider)
await l1WalletOnL2.sendTransaction({
to,
......@@ -76,7 +77,16 @@ const privKey = process.env.PRIVATE_KEY || '0x' + '11'.repeat(32)
* @type import("hardhat/config").HardhatUserConfig
*/
module.exports = {
solidity: '0.8.12',
solidity: {
version: '0.8.12',
settings: {
outputSelection: {
'*': {
'*': ['metadata', 'storageLayout'],
},
},
},
},
networks: {
optimism: {
chainId: 17,
......
......@@ -28,6 +28,7 @@
"deploy:mainnet": "hardhat deploy-token --network 'optimism-mainnet'"
},
"dependencies": {
"@eth-optimism/core-utils": "^0.8.7",
"@eth-optimism/sdk": "^1.1.9",
"@ethersproject/hardware-wallets": "^5.6.1",
"@nomiclabs/hardhat-ethers": "^2.0.2",
......@@ -37,8 +38,8 @@
"@openzeppelin/contracts": "4.5.0",
"commander": "^9.3.0",
"csv-parse": "^5.0.4",
"ethereumjs-util": "^7.1.4",
"eth-sig-util": "^3.0.1",
"ethereumjs-util": "^7.1.4",
"ethers": "^5.6.8",
"hardhat": "^2.9.6"
},
......
......@@ -181,8 +181,8 @@ contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled {
bytes calldata _data
) internal {
// When a deposit is initiated on L1, the L1 Bridge transfers the funds to itself for future
// withdrawals. safeTransferFrom also checks if the contract has code, so this will fail if
// _from is an EOA or address(0).
// withdrawals. The use of safeTransferFrom enables support of "broken tokens" which do not
// return a boolean value.
// slither-disable-next-line reentrancy-events, reentrancy-benign
IERC20(_l1Token).safeTransferFrom(_from, address(this), _amount);
......
......@@ -5,8 +5,8 @@
*/
export interface State {
[address: string]: {
nonce: number
balance: string
nonce?: string
balance?: string
codeHash?: string
root?: string
code?: string
......@@ -24,6 +24,7 @@ export interface ChainConfig {
chainId: number
homesteadBlock: number
eip150Block: number
eip150Hash?: string
eip155Block: number
eip158Block: number
byzantiumBlock: number
......@@ -34,6 +35,7 @@ export interface ChainConfig {
berlinBlock: number
londonBlock?: number
arrowGlacierBlock?: number
grayGlacierBlock?: number
mergeForkBlock?: number
terminalTotalDifficulty?: number
clique?: {
......@@ -48,12 +50,31 @@ export interface ChainConfig {
*/
export interface Genesis {
config: ChainConfig
nonce?: number
timestamp?: number
nonce?: string
timestamp?: string
difficulty: string
mixHash?: string
coinbase?: string
number?: string
gasLimit: string
gasUsed?: string
parentHash?: string
extraData: string
alloc: State
}
/**
* Represents the chain config for an Optimism chain
*/
export interface OptimismChainConfig {
enabled: boolean
baseFeeRecipient: string
l1FeeRecipient: string
}
/**
* Represents the Genesis file format for an Optimism chain
*/
export interface OptimismGenesis extends Genesis {
optimism: OptimismChainConfig
}
......@@ -6,3 +6,4 @@ export * from './alias'
export * from './batch-encoding'
export * from './fees'
export * from './rollup-types'
export * from './op-node'
export interface OpNodeConfig {
genesis: {
l1: {
hash: string
number: number
}
l2: {
hash: string
number: number
}
l2_time: number
}
block_time: number
max_sequencer_drift: number
seq_window_size: number
l1_chain_id: number
l2_chain_id: number
p2p_sequencer_address: string
fee_recipient_address: string
batch_inbox_address: string
batch_sender_address: string
deposit_contract_address: string
}
......@@ -81,6 +81,7 @@ export class FaultDetector extends BaseServiceV2<Options, Metrics, State> {
l1SignerOrProvider: this.options.l1RpcProvider,
l2SignerOrProvider: this.options.l2RpcProvider,
l1ChainId: await getChainId(this.options.l1RpcProvider),
l2ChainId: await getChainId(this.options.l2RpcProvider),
})
// We use this a lot, a bit cleaner to pull out to the top level of the state object.
......@@ -135,6 +136,16 @@ export class FaultDetector extends BaseServiceV2<Options, Metrics, State> {
const batchStart = event.args._prevTotalElements.toNumber() + 1
const batchSize = event.args._batchSize.toNumber()
const batchEnd = batchStart + batchSize
const latestBlock = await this.options.l2RpcProvider.getBlockNumber()
if (latestBlock < batchEnd) {
this.logger.info(`node is behind, waiting for sync`, {
batchEnd,
latestBlock,
})
return
}
// `getBlockRange` has a limit of 1000 blocks, so we have to break this request out into
// multiple requests of maximum 1000 blocks in the case that batchSize > 1000.
......
......@@ -33,8 +33,8 @@ const getTargetOutput = async (
withdrawalTimestamp: number
) => {
const submissionInterval = (await oracle.SUBMISSION_INTERVAL()).toNumber()
const startingBlockTimestamp = (
await oracle.STARTING_BLOCK_TIMESTAMP()
const startingTimestamp = (
await oracle.STARTING_TIMESTAMP()
).toNumber()
const nextTimestamp = (await oracle.nextTimestamp()).toNumber()
let targetOutputTimestamp
......@@ -45,10 +45,10 @@ const getTargetOutput = async (
// Calculate the first timestamp greater than the burnBlock which will be appended.
targetOutputTimestamp =
Math.ceil(
(withdrawalTimestamp - startingBlockTimestamp) / submissionInterval
(withdrawalTimestamp - startingTimestamp) / submissionInterval
) *
submissionInterval +
startingBlockTimestamp
startingTimestamp
}
return targetOutputTimestamp
......
......@@ -89,6 +89,7 @@ export class MessageRelayerService extends BaseServiceV2<
l1SignerOrProvider: this.state.wallet,
l2SignerOrProvider: this.options.l2RpcProvider,
l1ChainId: await getChainId(this.state.wallet.provider),
l2ChainId: await getChainId(this.options.l2RpcProvider),
})
this.state.highestCheckedL2Tx = this.options.fromL2TransactionIndex || 1
......
......@@ -54,6 +54,7 @@ export class CrossChainMessenger implements ICrossChainMessenger {
public l1SignerOrProvider: Signer | Provider
public l2SignerOrProvider: Signer | Provider
public l1ChainId: number
public l2ChainId: number
public contracts: OEContracts
public bridges: BridgeAdapters
public depositConfirmationBlocks: number
......@@ -66,6 +67,7 @@ export class CrossChainMessenger implements ICrossChainMessenger {
* @param opts.l1SignerOrProvider Signer or Provider for the L1 chain, or a JSON-RPC url.
* @param opts.l2SignerOrProvider Signer or Provider for the L2 chain, or a JSON-RPC url.
* @param opts.l1ChainId Chain ID for the L1 chain.
* @param opts.l2ChainId Chain ID for the L2 chain.
* @param opts.depositConfirmationBlocks Optional number of blocks before a deposit is confirmed.
* @param opts.l1BlockTimeSeconds Optional estimated block time in seconds for the L1 chain.
* @param opts.contracts Optional contract address overrides.
......@@ -75,6 +77,7 @@ export class CrossChainMessenger implements ICrossChainMessenger {
l1SignerOrProvider: SignerOrProviderLike
l2SignerOrProvider: SignerOrProviderLike
l1ChainId: NumberLike
l2ChainId: NumberLike
depositConfirmationBlocks?: NumberLike
l1BlockTimeSeconds?: NumberLike
contracts?: DeepPartial<OEContractsLike>
......@@ -83,24 +86,25 @@ export class CrossChainMessenger implements ICrossChainMessenger {
this.l1SignerOrProvider = toSignerOrProvider(opts.l1SignerOrProvider)
this.l2SignerOrProvider = toSignerOrProvider(opts.l2SignerOrProvider)
this.l1ChainId = toNumber(opts.l1ChainId)
this.l2ChainId = toNumber(opts.l2ChainId)
this.depositConfirmationBlocks =
opts?.depositConfirmationBlocks !== undefined
? toNumber(opts.depositConfirmationBlocks)
: DEPOSIT_CONFIRMATION_BLOCKS[this.l1ChainId] || 0
: DEPOSIT_CONFIRMATION_BLOCKS[this.l2ChainId] || 0
this.l1BlockTimeSeconds =
opts?.l1BlockTimeSeconds !== undefined
? toNumber(opts.l1BlockTimeSeconds)
: CHAIN_BLOCK_TIMES[this.l1ChainId] || 1
this.contracts = getAllOEContracts(this.l1ChainId, {
this.contracts = getAllOEContracts(this.l2ChainId, {
l1SignerOrProvider: this.l1SignerOrProvider,
l2SignerOrProvider: this.l2SignerOrProvider,
overrides: opts.contracts,
})
this.bridges = getBridgeAdapters(this.l1ChainId, this, {
this.bridges = getBridgeAdapters(this.l2ChainId, this, {
overrides: opts.bridges,
})
}
......
......@@ -46,6 +46,11 @@ export interface ICrossChainMessenger {
*/
l1ChainId: number
/**
* Chain ID for the L2 network.
*/
l2ChainId: number
/**
* Contract objects attached to their respective providers and addresses.
*/
......
......@@ -10,15 +10,26 @@ import { ICrossChainMessenger } from './cross-chain-messenger'
import { IBridgeAdapter } from './bridge-adapter'
/**
* Commonly used Chain IDs
* L1 network chain IDs
*/
export enum Chain {
export enum L1ChainID {
MAINNET = 1,
GOERLI = 5,
KOVAN = 42,
HARDHAT_LOCAL = 31337,
}
/**
* L2 network chain IDs
*/
export enum L2ChainID {
OPTIMISM = 10,
OPTIMISM_GOERLI = 420,
OPTIMISM_KOVAN = 69,
OPTIMISM_HARDHAT_LOCAL = 31337,
OPTIMISM_HARDHAT_DEVNET = 17,
}
/**
* L1 contract references.
*/
......
import { Chain } from '../interfaces'
import { L1ChainID, L2ChainID } from '../interfaces'
export const DEPOSIT_CONFIRMATION_BLOCKS = {
[Chain.MAINNET]: 50 as const,
[Chain.GOERLI]: 12 as const,
[Chain.KOVAN]: 12 as const,
// 2 just for testing purposes
[Chain.HARDHAT_LOCAL]: 2 as const,
export const DEPOSIT_CONFIRMATION_BLOCKS: {
[ChainID in L2ChainID]: number
} = {
[L2ChainID.OPTIMISM]: 50 as const,
[L2ChainID.OPTIMISM_GOERLI]: 12 as const,
[L2ChainID.OPTIMISM_KOVAN]: 12 as const,
[L2ChainID.OPTIMISM_HARDHAT_LOCAL]: 2 as const,
[L2ChainID.OPTIMISM_HARDHAT_DEVNET]: 2 as const,
}
export const CHAIN_BLOCK_TIMES = {
[Chain.MAINNET]: 13 as const,
[Chain.GOERLI]: 15 as const,
[Chain.KOVAN]: 4 as const,
[Chain.HARDHAT_LOCAL]: 1 as const,
export const CHAIN_BLOCK_TIMES: {
[ChainID in L1ChainID]: number
} = {
[L1ChainID.MAINNET]: 13 as const,
[L1ChainID.GOERLI]: 15 as const,
[L1ChainID.KOVAN]: 4 as const,
[L1ChainID.HARDHAT_LOCAL]: 1 as const,
}
......@@ -13,7 +13,7 @@ import {
BridgeAdapters,
BridgeAdapterData,
ICrossChainMessenger,
Chain,
L2ChainID,
} from '../interfaces'
import {
StandardBridgeAdapter,
......@@ -52,9 +52,9 @@ const NAME_REMAPPING = {
* contract name.
*/
export const CONTRACT_ADDRESSES: {
[l1ChainId: number]: OEContractsLike
[ChainID in L2ChainID]: OEContractsLike
} = {
[Chain.MAINNET]: {
[L2ChainID.OPTIMISM]: {
l1: {
AddressManager: '0xdE1FCfB0851916CA5101820A69b13a4E276bd81F' as const,
L1CrossDomainMessenger:
......@@ -68,7 +68,7 @@ export const CONTRACT_ADDRESSES: {
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
},
[Chain.KOVAN]: {
[L2ChainID.OPTIMISM_KOVAN]: {
l1: {
AddressManager: '0x100Dd3b414Df5BbA2B542864fF94aF8024aFdf3a' as const,
L1CrossDomainMessenger:
......@@ -82,7 +82,7 @@ export const CONTRACT_ADDRESSES: {
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
},
[Chain.GOERLI]: {
[L2ChainID.OPTIMISM_GOERLI]: {
l1: {
AddressManager: '0x2F7E3cAC91b5148d336BbffB224B4dC79F09f01D' as const,
L1CrossDomainMessenger:
......@@ -96,7 +96,21 @@ export const CONTRACT_ADDRESSES: {
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
},
[Chain.HARDHAT_LOCAL]: {
[L2ChainID.OPTIMISM_HARDHAT_LOCAL]: {
l1: {
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,
},
[L2ChainID.OPTIMISM_HARDHAT_DEVNET]: {
l1: {
AddressManager: '0x5FbDB2315678afecb367f032d93F642f64180aa3' as const,
L1CrossDomainMessenger:
......@@ -116,21 +130,9 @@ export const CONTRACT_ADDRESSES: {
* Mapping of L1 chain IDs to the list of custom bridge addresses for each chain.
*/
export const BRIDGE_ADAPTER_DATA: {
[l1ChainId: number]: BridgeAdapterData
[ChainID in L2ChainID]?: BridgeAdapterData
} = {
// TODO: Maybe we can pull these automatically from the token list?
// Alternatively, check against the token list in CI.
[Chain.MAINNET]: {
Standard: {
Adapter: StandardBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[1].l1.L1StandardBridge,
l2Bridge: predeploys.L2StandardBridge,
},
ETH: {
Adapter: ETHBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[1].l1.L1StandardBridge,
l2Bridge: predeploys.L2StandardBridge,
},
[L2ChainID.OPTIMISM]: {
BitBTC: {
Adapter: StandardBridgeAdapter,
l1Bridge: '0xaBA2c5F108F7E820C049D5Af70B16ac266c8f128' as const,
......@@ -142,17 +144,7 @@ export const BRIDGE_ADAPTER_DATA: {
l2Bridge: '0x467194771dAe2967Aef3ECbEDD3Bf9a310C76C65' as const,
},
},
[Chain.KOVAN]: {
Standard: {
Adapter: StandardBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[42].l1.L1StandardBridge,
l2Bridge: predeploys.L2StandardBridge,
},
ETH: {
Adapter: ETHBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[42].l1.L1StandardBridge,
l2Bridge: predeploys.L2StandardBridge,
},
[L2ChainID.OPTIMISM_KOVAN]: {
BitBTC: {
Adapter: StandardBridgeAdapter,
l1Bridge: '0x0b651A42F32069d62d5ECf4f2a7e5Bd3E9438746' as const,
......@@ -169,56 +161,16 @@ export const BRIDGE_ADAPTER_DATA: {
l2Bridge: '0x467194771dAe2967Aef3ECbEDD3Bf9a310C76C65' as const,
},
},
[Chain.GOERLI]: {
Standard: {
Adapter: StandardBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[5].l1.L1StandardBridge,
l2Bridge: predeploys.L2StandardBridge,
},
ETH: {
Adapter: ETHBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[5].l1.L1StandardBridge,
l2Bridge: predeploys.L2StandardBridge,
},
},
[Chain.HARDHAT_LOCAL]: {
Standard: {
Adapter: StandardBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[31337].l1.L1StandardBridge,
l2Bridge: predeploys.L2StandardBridge,
},
ETH: {
Adapter: ETHBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[31337].l1.L1StandardBridge,
l2Bridge: predeploys.L2StandardBridge,
},
},
}
// TODO: PR is big enough as-is, will add support for SNX in another PR
// MAINNET
// l1: {
// SNX: '0xCd9D4988C0AE61887B075bA77f08cbFAd2b65068',
// },
// l2: {
// SNX: '0x3f87Ff1de58128eF8FCb4c807eFD776E1aC72E51',
// },
// KOVAN
// l1: {
// SNX: '0xD134Db47DDF5A6feB245452af17cCAf92ee53D3c',
// },
// l2: {
// SNX: '0x5C3f51CEd0C2F6157e2be67c029264D6C44bfe42',
// },
/**
* Returns an ethers.Contract object for the given name, connected to the appropriate address for
* the given L1 chain ID. Users can also provide a custom address to connect the contract to
* the given L2 chain ID. Users can also provide a custom address to connect the contract to
* instead. If the chain ID is not known then the user MUST provide a custom address or this
* function will throw an error.
*
* @param contractName Name of the contract to connect to.
* @param l1ChainId Chain ID for the L1 network where the OE contracts are deployed.
* @param l2ChainId Chain ID for the L2 network.
* @param opts Additional options for connecting to the contract.
* @param opts.address Custom address to connect to the contract.
* @param opts.signerOrProvider Signer or provider to connect to the contract.
......@@ -226,16 +178,16 @@ export const BRIDGE_ADAPTER_DATA: {
*/
export const getOEContract = (
contractName: keyof OEL1Contracts | keyof OEL2Contracts,
l1ChainId: number,
l2ChainId: number,
opts: {
address?: AddressLike
signerOrProvider?: ethers.Signer | ethers.providers.Provider
} = {}
): Contract => {
const addresses = CONTRACT_ADDRESSES[l1ChainId]
const addresses = CONTRACT_ADDRESSES[l2ChainId]
if (addresses === undefined && opts.address === undefined) {
throw new Error(
`cannot get contract ${contractName} for unknown L1 chain ID ${l1ChainId}, you must provide an address`
`cannot get contract ${contractName} for unknown L2 chain ID ${l2ChainId}, you must provide an address`
)
}
......@@ -249,12 +201,12 @@ export const getOEContract = (
}
/**
* Automatically connects to all contract addresses, both L1 and L2, for the given L1 chain ID. The
* Automatically connects to all contract addresses, both L1 and L2, for the given L2 chain ID. The
* user can provide custom contract address overrides for L1 or L2 contracts. If the given chain ID
* is not known then the user MUST provide custom contract addresses for ALL L1 contracts or this
* function will throw an error.
*
* @param l1ChainId Chain ID for the L1 network where the OE contracts are deployed.
* @param l2ChainId Chain ID for the L2 network.
* @param opts Additional options for connecting to the contracts.
* @param opts.l1SignerOrProvider: Signer or provider to connect to the L1 contracts.
* @param opts.l2SignerOrProvider: Signer or provider to connect to the L2 contracts.
......@@ -263,14 +215,14 @@ export const getOEContract = (
* both L1 and L2.
*/
export const getAllOEContracts = (
l1ChainId: number,
l2ChainId: number,
opts: {
l1SignerOrProvider?: ethers.Signer | ethers.providers.Provider
l2SignerOrProvider?: ethers.Signer | ethers.providers.Provider
overrides?: DeepPartial<OEContractsLike>
} = {}
): OEContracts => {
const addresses = CONTRACT_ADDRESSES[l1ChainId] || {
const addresses = CONTRACT_ADDRESSES[l2ChainId] || {
l1: {
AddressManager: undefined,
L1CrossDomainMessenger: undefined,
......@@ -287,7 +239,7 @@ export const getAllOEContracts = (
for (const [contractName, contractAddress] of Object.entries(addresses.l1)) {
l1Contracts[contractName] = getOEContract(
contractName as keyof OEL1Contracts,
l1ChainId,
l2ChainId,
{
address: opts.overrides?.l1?.[contractName] || contractAddress,
signerOrProvider: opts.l1SignerOrProvider,
......@@ -300,7 +252,7 @@ export const getAllOEContracts = (
for (const [contractName, contractAddress] of Object.entries(addresses.l2)) {
l2Contracts[contractName] = getOEContract(
contractName as keyof OEL2Contracts,
l1ChainId,
l2ChainId,
{
address: opts.overrides?.l2?.[contractName] || contractAddress,
signerOrProvider: opts.l2SignerOrProvider,
......@@ -315,26 +267,42 @@ export const getAllOEContracts = (
}
/**
* Gets a series of bridge adapters for the given L1 chain ID.
* Gets a series of bridge adapters for the given L2 chain ID.
*
* @param l1ChainId L1 chain ID for the L1 network where the custom bridges are deployed.
* @param l2ChainId Chain ID for the L2 network.
* @param messenger Cross chain messenger to connect to the bridge adapters
* @param opts Additional options for connecting to the custom bridges.
* @param opts.overrides Custom bridge adapters.
* @returns An object containing all bridge adapters
*/
export const getBridgeAdapters = (
l1ChainId: number,
l2ChainId: number,
messenger: ICrossChainMessenger,
opts?: {
overrides?: BridgeAdapterData
}
): BridgeAdapters => {
const adapters: BridgeAdapters = {}
for (const [bridgeName, bridgeData] of Object.entries({
...(BRIDGE_ADAPTER_DATA[l1ChainId] || {}),
const adapterData: BridgeAdapterData = {
...(CONTRACT_ADDRESSES[l2ChainId]
? {
Standard: {
Adapter: StandardBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[l2ChainId].l1.L1StandardBridge,
l2Bridge: predeploys.L2StandardBridge,
},
ETH: {
Adapter: ETHBridgeAdapter,
l1Bridge: CONTRACT_ADDRESSES[l2ChainId].l1.L1StandardBridge,
l2Bridge: predeploys.L2StandardBridge,
},
}
: {}),
...(BRIDGE_ADAPTER_DATA[l2ChainId] || {}),
...(opts?.overrides || {}),
})) {
}
const adapters: BridgeAdapters = {}
for (const [bridgeName, bridgeData] of Object.entries(adapterData)) {
adapters[bridgeName] = new bridgeData.Adapter({
messenger,
l1Bridge: bridgeData.l1Bridge,
......
......@@ -15,6 +15,8 @@ import {
CrossChainMessenger,
StandardBridgeAdapter,
ETHBridgeAdapter,
L1ChainID,
L2ChainID,
} from '../src'
import { DUMMY_MESSAGE } from './helpers'
......@@ -31,7 +33,8 @@ describe('CrossChainMessenger', () => {
const messenger = new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: ethers.provider,
l1ChainId: 1,
l1ChainId: L1ChainID.MAINNET,
l2ChainId: L2ChainID.OPTIMISM,
})
expect(messenger.l1Provider).to.equal(ethers.provider)
......@@ -43,7 +46,8 @@ describe('CrossChainMessenger', () => {
const messenger = new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: ethers.provider,
l1ChainId: 1,
l1ChainId: L1ChainID.MAINNET,
l2ChainId: L2ChainID.OPTIMISM,
})
expect(messenger.l2Provider).to.equal(ethers.provider)
......@@ -55,7 +59,8 @@ describe('CrossChainMessenger', () => {
const messenger = new CrossChainMessenger({
l1SignerOrProvider: 'https://localhost:8545',
l2SignerOrProvider: ethers.provider,
l1ChainId: 1,
l1ChainId: L1ChainID.MAINNET,
l2ChainId: L2ChainID.OPTIMISM,
})
expect(Provider.isProvider(messenger.l1Provider)).to.be.true
......@@ -67,7 +72,8 @@ describe('CrossChainMessenger', () => {
const messenger = new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: 'https://localhost:8545',
l1ChainId: 1,
l1ChainId: L1ChainID.MAINNET,
l2ChainId: L2ChainID.OPTIMISM,
})
expect(Provider.isProvider(messenger.l2Provider)).to.be.true
......@@ -80,10 +86,11 @@ describe('CrossChainMessenger', () => {
const messenger = new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: 'https://localhost:8545',
l1ChainId: 1,
l1ChainId: L1ChainID.MAINNET,
l2ChainId: L2ChainID.OPTIMISM,
})
const addresses = CONTRACT_ADDRESSES[1]
const addresses = CONTRACT_ADDRESSES[messenger.l2ChainId]
for (const [contractName, contractAddress] of Object.entries(
addresses.l1
)) {
......@@ -99,13 +106,14 @@ describe('CrossChainMessenger', () => {
})
})
describe('when given an unknown chain ID', () => {
describe('when given an unknown L2 chain ID', () => {
it('should throw an error', () => {
expect(() => {
new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: 'https://localhost:8545',
l1ChainId: 1234,
l1ChainId: L1ChainID.MAINNET,
l2ChainId: 1234,
})
}).to.throw()
})
......@@ -126,11 +134,12 @@ describe('CrossChainMessenger', () => {
const messenger = new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: 'https://localhost:8545',
l1ChainId: 1,
l1ChainId: L1ChainID.MAINNET,
l2ChainId: L2ChainID.OPTIMISM,
contracts: overrides,
})
const addresses = CONTRACT_ADDRESSES[1]
const addresses = CONTRACT_ADDRESSES[messenger.l2ChainId]
for (const [contractName, contractAddress] of Object.entries(
addresses.l1
)) {
......@@ -156,7 +165,7 @@ describe('CrossChainMessenger', () => {
})
})
describe('when given an unknown chain ID', () => {
describe('when given an unknown L2 chain ID', () => {
describe('when all L1 addresses are provided', () => {
it('should use custom addresses where provided', () => {
const overrides = {
......@@ -172,14 +181,16 @@ describe('CrossChainMessenger', () => {
L2CrossDomainMessenger: '0x' + '22'.repeat(20),
},
}
const messenger = new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: 'https://localhost:8545',
l1ChainId: 1234,
l1ChainId: L1ChainID.MAINNET,
l2ChainId: 1234,
contracts: overrides,
})
const addresses = CONTRACT_ADDRESSES[1]
const addresses = CONTRACT_ADDRESSES[L2ChainID.OPTIMISM]
for (const [contractName, contractAddress] of Object.entries(
addresses.l1
)) {
......@@ -211,7 +222,8 @@ describe('CrossChainMessenger', () => {
new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: 'https://localhost:8545',
l1ChainId: 1234,
l1ChainId: L1ChainID.MAINNET,
l2ChainId: 1234,
contracts: {
l1: {
// Missing some required L1 addresses
......@@ -246,7 +258,8 @@ describe('CrossChainMessenger', () => {
messenger = new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: ethers.provider,
l1ChainId: 31337,
l1ChainId: L1ChainID.HARDHAT_LOCAL,
l2ChainId: L2ChainID.OPTIMISM_HARDHAT_LOCAL,
contracts: {
l1: {
L1CrossDomainMessenger: l1Messenger.address,
......@@ -433,7 +446,8 @@ describe('CrossChainMessenger', () => {
messenger = new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: ethers.provider,
l1ChainId: 31337,
l1ChainId: L1ChainID.HARDHAT_LOCAL,
l2ChainId: L2ChainID.OPTIMISM_HARDHAT_LOCAL,
contracts: {
l1: {
L1CrossDomainMessenger: l1Messenger.address,
......@@ -557,7 +571,8 @@ describe('CrossChainMessenger', () => {
messenger = new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: ethers.provider,
l1ChainId: 31337,
l1ChainId: L1ChainID.HARDHAT_LOCAL,
l2ChainId: L2ChainID.OPTIMISM_HARDHAT_LOCAL,
contracts: {
l1: {
L1CrossDomainMessenger: l1Messenger.address,
......@@ -761,7 +776,8 @@ describe('CrossChainMessenger', () => {
messenger = new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: ethers.provider,
l1ChainId: 31337,
l1ChainId: L1ChainID.HARDHAT_LOCAL,
l2ChainId: L2ChainID.OPTIMISM_HARDHAT_LOCAL,
contracts: {
l1: {
L1CrossDomainMessenger: l1Messenger.address,
......@@ -910,7 +926,8 @@ describe('CrossChainMessenger', () => {
messenger = new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: ethers.provider,
l1ChainId: 31337,
l1ChainId: L1ChainID.HARDHAT_LOCAL,
l2ChainId: L2ChainID.OPTIMISM_HARDHAT_LOCAL,
contracts: {
l2: {
L2CrossDomainMessenger: l2Messenger.address,
......@@ -1014,7 +1031,8 @@ describe('CrossChainMessenger', () => {
messenger = new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: ethers.provider,
l1ChainId: 31337,
l1ChainId: L1ChainID.HARDHAT_LOCAL,
l2ChainId: L2ChainID.OPTIMISM_HARDHAT_LOCAL,
})
})
......@@ -1117,7 +1135,8 @@ describe('CrossChainMessenger', () => {
messenger = new CrossChainMessenger({
l1SignerOrProvider: ethers.provider,
l2SignerOrProvider: ethers.provider,
l1ChainId: 31337,
l1ChainId: L1ChainID.HARDHAT_LOCAL,
l2ChainId: L2ChainID.OPTIMISM_HARDHAT_LOCAL,
contracts: {
l1: {
L1CrossDomainMessenger: l1Messenger.address,
......@@ -1275,7 +1294,8 @@ describe('CrossChainMessenger', () => {
messenger = new CrossChainMessenger({
l1SignerOrProvider: l1Signer,
l2SignerOrProvider: l2Signer,
l1ChainId: 31337,
l1ChainId: L1ChainID.HARDHAT_LOCAL,
l2ChainId: L2ChainID.OPTIMISM_HARDHAT_LOCAL,
contracts: {
l1: {
L1CrossDomainMessenger: l1Messenger.address,
......@@ -1370,7 +1390,8 @@ describe('CrossChainMessenger', () => {
messenger = new CrossChainMessenger({
l1SignerOrProvider: l1Signer,
l2SignerOrProvider: l2Signer,
l1ChainId: 31337,
l1ChainId: L1ChainID.HARDHAT_LOCAL,
l2ChainId: L2ChainID.OPTIMISM_HARDHAT_LOCAL,
contracts: {
l1: {
L1CrossDomainMessenger: l1Messenger.address,
......@@ -1466,7 +1487,8 @@ describe('CrossChainMessenger', () => {
messenger = new CrossChainMessenger({
l1SignerOrProvider: l1Signer,
l2SignerOrProvider: l2Signer,
l1ChainId: 31337,
l1ChainId: L1ChainID.HARDHAT_LOCAL,
l2ChainId: L2ChainID.OPTIMISM_HARDHAT_LOCAL,
contracts: {
l1: {
L1CrossDomainMessenger: l1Messenger.address,
......@@ -1522,7 +1544,8 @@ describe('CrossChainMessenger', () => {
messenger = new CrossChainMessenger({
l1SignerOrProvider: l1Signer,
l2SignerOrProvider: l2Signer,
l1ChainId: 31337,
l1ChainId: L1ChainID.HARDHAT_LOCAL,
l2ChainId: L2ChainID.OPTIMISM_HARDHAT_LOCAL,
contracts: {
l1: {
L1CrossDomainMessenger: l1Messenger.address,
......
......@@ -8,6 +8,7 @@ import {
getAllOEContracts,
CONTRACT_ADDRESSES,
DEFAULT_L2_CONTRACT_ADDRESSES,
L2ChainID,
} from '../../src'
describe('contract connection utils', () => {
......@@ -20,12 +21,15 @@ describe('contract connection utils', () => {
describe('when given a known chain ID', () => {
describe('when not given an address override', () => {
it('should use the address for the given contract name and chain ID', () => {
const addresses = CONTRACT_ADDRESSES[1]
const addresses = CONTRACT_ADDRESSES[L2ChainID.OPTIMISM]
for (const [contractName, contractAddress] of [
...Object.entries(addresses.l1),
...Object.entries(addresses.l2),
]) {
const contract = getOEContract(contractName as any, 1)
const contract = getOEContract(
contractName as any,
L2ChainID.OPTIMISM
)
expect(contract.address).to.equal(contractAddress)
}
})
......@@ -33,7 +37,7 @@ describe('contract connection utils', () => {
describe('when given an address override', () => {
it('should use the custom address', () => {
const addresses = CONTRACT_ADDRESSES[1]
const addresses = CONTRACT_ADDRESSES[L2ChainID.OPTIMISM]
for (const contractName of [
...Object.keys(addresses.l1),
...Object.keys(addresses.l2),
......@@ -68,13 +72,19 @@ describe('contract connection utils', () => {
describe('when connected to a valid address', () => {
it('should have the correct interface for the contract name', () => {
const contract = getOEContract('L1CrossDomainMessenger', 1)
const contract = getOEContract(
'L1CrossDomainMessenger',
L2ChainID.OPTIMISM
)
expect(contract.sendMessage).to.not.be.undefined
})
describe('when not given a signer or provider', () => {
it('should not have a signer or provider', () => {
const contract = getOEContract('L1CrossDomainMessenger', 1)
const contract = getOEContract(
'L1CrossDomainMessenger',
L2ChainID.OPTIMISM
)
expect(contract.signer).to.be.null
expect(contract.provider).to.be.null
})
......@@ -82,18 +92,26 @@ describe('contract connection utils', () => {
describe('when given a signer', () => {
it('should attach the given signer', () => {
const contract = getOEContract('L1CrossDomainMessenger', 1, {
signerOrProvider: signers[0],
})
const contract = getOEContract(
'L1CrossDomainMessenger',
L2ChainID.OPTIMISM,
{
signerOrProvider: signers[0],
}
)
expect(contract.signer).to.deep.equal(signers[0])
})
})
describe('when given a provider', () => {
it('should attach the given provider', () => {
const contract = getOEContract('L1CrossDomainMessenger', 1, {
signerOrProvider: ethers.provider as any,
})
const contract = getOEContract(
'L1CrossDomainMessenger',
L2ChainID.OPTIMISM,
{
signerOrProvider: ethers.provider as any,
}
)
expect(contract.signer).to.be.null
expect(contract.provider).to.deep.equal(ethers.provider)
})
......@@ -105,8 +123,8 @@ describe('contract connection utils', () => {
describe('when given a known chain ID', () => {
describe('when not given any address overrides', () => {
it('should return all contracts connected to the default addresses', () => {
const contracts = getAllOEContracts(1)
const addresses = CONTRACT_ADDRESSES[1]
const contracts = getAllOEContracts(L2ChainID.OPTIMISM)
const addresses = CONTRACT_ADDRESSES[L2ChainID.OPTIMISM]
for (const [contractName, contractAddress] of Object.entries(
addresses.l1
)) {
......@@ -132,8 +150,8 @@ describe('contract connection utils', () => {
L2CrossDomainMessenger: '0x' + '22'.repeat(20),
},
}
const contracts = getAllOEContracts(1, { overrides })
const addresses = CONTRACT_ADDRESSES[1]
const contracts = getAllOEContracts(L2ChainID.OPTIMISM, { overrides })
const addresses = CONTRACT_ADDRESSES[L2ChainID.OPTIMISM]
for (const [contractName, contractAddress] of Object.entries(
addresses.l1
)) {
......@@ -163,7 +181,9 @@ describe('contract connection utils', () => {
describe('when given address overrides for L2 contracts', () => {
it('should return contracts connected to the overridden addresses where given', () => {
const l1Overrides = {}
for (const contractName of Object.keys(CONTRACT_ADDRESSES[1].l1)) {
for (const contractName of Object.keys(
CONTRACT_ADDRESSES[L2ChainID.OPTIMISM].l1
)) {
l1Overrides[contractName] = '0x' + '11'.repeat(20)
}
......@@ -191,7 +211,9 @@ describe('contract connection utils', () => {
describe('when not given address overrides for L2 contracts', () => {
it('should return contracts connected to the default L2 addresses and custom L1 addresses', () => {
const l1Overrides = {}
for (const contractName of Object.keys(CONTRACT_ADDRESSES[1].l1)) {
for (const contractName of Object.keys(
CONTRACT_ADDRESSES[L2ChainID.OPTIMISM].l1
)) {
l1Overrides[contractName] = '0x' + '11'.repeat(20)
}
......@@ -241,7 +263,7 @@ describe('contract connection utils', () => {
describe('when not given a signer or provider', () => {
it('should not attach a signer or provider to any contracts', () => {
const contracts = getAllOEContracts(1)
const contracts = getAllOEContracts(L2ChainID.OPTIMISM)
for (const contract of Object.values(contracts.l1)) {
expect(contract.signer).to.be.null
expect(contract.provider).to.be.null
......@@ -255,7 +277,7 @@ describe('contract connection utils', () => {
describe('when given an L1 signer', () => {
it('should attach the signer to the L1 contracts only', () => {
const contracts = getAllOEContracts(1, {
const contracts = getAllOEContracts(L2ChainID.OPTIMISM, {
l1SignerOrProvider: signers[0],
})
for (const contract of Object.values(contracts.l1)) {
......@@ -270,7 +292,7 @@ describe('contract connection utils', () => {
describe('when given an L2 signer', () => {
it('should attach the signer to the L2 contracts only', () => {
const contracts = getAllOEContracts(1, {
const contracts = getAllOEContracts(L2ChainID.OPTIMISM, {
l2SignerOrProvider: signers[0],
})
for (const contract of Object.values(contracts.l1)) {
......@@ -285,7 +307,7 @@ describe('contract connection utils', () => {
describe('when given an L1 signer and an L2 signer', () => {
it('should attach the signer to both sets of contracts', () => {
const contracts = getAllOEContracts(1, {
const contracts = getAllOEContracts(L2ChainID.OPTIMISM, {
l1SignerOrProvider: signers[0],
l2SignerOrProvider: signers[1],
})
......@@ -300,7 +322,7 @@ describe('contract connection utils', () => {
describe('when given an L1 provider', () => {
it('should attach the provider to the L1 contracts only', () => {
const contracts = getAllOEContracts(1, {
const contracts = getAllOEContracts(L2ChainID.OPTIMISM, {
l1SignerOrProvider: ethers.provider as any,
})
for (const contract of Object.values(contracts.l1)) {
......@@ -316,7 +338,7 @@ describe('contract connection utils', () => {
describe('when given an L2 provider', () => {
it('should attach the provider to the L2 contracts only', () => {
const contracts = getAllOEContracts(1, {
const contracts = getAllOEContracts(L2ChainID.OPTIMISM, {
l2SignerOrProvider: ethers.provider as any,
})
for (const contract of Object.values(contracts.l1)) {
......@@ -332,7 +354,7 @@ describe('contract connection utils', () => {
describe('when given an L1 provider and an L2 provider', () => {
it('should attach the provider to both sets of contracts', () => {
const contracts = getAllOEContracts(1, {
const contracts = getAllOEContracts(L2ChainID.OPTIMISM, {
l1SignerOrProvider: ethers.provider as any,
l2SignerOrProvider: ethers.provider as any,
})
......
......@@ -231,9 +231,7 @@ func (m *MockBackend) Requests() []*RecordedRequest {
m.mtx.RLock()
defer m.mtx.RUnlock()
out := make([]*RecordedRequest, len(m.requests))
for i := 0; i < len(m.requests); i++ {
out[i] = m.requests[i]
}
copy(out, m.requests)
return out
}
......
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