Commit f56c2040 authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge branch 'develop' into clabby/op-challenger-devnet-hack

parents 5a364314 29c1f395
...@@ -861,8 +861,8 @@ jobs: ...@@ -861,8 +861,8 @@ jobs:
make devnet-up-deploy make devnet-up-deploy
- run: - run:
name: Check L2 config name: Check L2 config
command: npx hardhat check-l2 --network devnetL1 --l2-rpc-url http://localhost:9545 --l1-rpc-url http://localhost:8545 command: go run cmd/check-l2/main.go --l2-rpc-url http://localhost:9545 --l1-rpc-url http://localhost:8545
working_directory: packages/contracts-bedrock working_directory: op-chain-ops
- run: - run:
name: Deposit ERC20 through the bridge name: Deposit ERC20 through the bridge
command: timeout 8m npx hardhat deposit-erc20 --network devnetL1 --l1-contracts-json-path ../../.devnet/sdk-addresses.json command: timeout 8m npx hardhat deposit-erc20 --network devnetL1 --l1-contracts-json-path ../../.devnet/sdk-addresses.json
...@@ -907,13 +907,8 @@ jobs: ...@@ -907,13 +907,8 @@ jobs:
make devnet-up make devnet-up
- run: - run:
name: Check L2 config name: Check L2 config
command: | command: go run cmd/check-l2/main.go --l2-rpc-url http://localhost:9545 --l1-rpc-url http://localhost:8545
npx hardhat check-l2 \ working_directory: op-chain-ops
--network devnetL1 \
--l2-rpc-url http://localhost:9545 \
--l1-rpc-url http://localhost:8545 \
--l2-output-oracle-address 0x6900000000000000000000000000000000000000
working_directory: packages/contracts-bedrock
- run: - run:
name: Deposit ERC20 through the bridge name: Deposit ERC20 through the bridge
command: timeout 10m npx hardhat deposit-erc20 --network devnetL1 command: timeout 10m npx hardhat deposit-erc20 --network devnetL1
......
...@@ -32,6 +32,7 @@ bindings: l1block-bindings \ ...@@ -32,6 +32,7 @@ bindings: l1block-bindings \
basefee-vault-bindings \ basefee-vault-bindings \
legacy-erc20-eth-bindings \ legacy-erc20-eth-bindings \
dispute-game-factory-bindings \ dispute-game-factory-bindings \
fault-dispute-game-bindings \
standard-bridge-bindings \ standard-bridge-bindings \
cross-domain-messenger-bindings \ cross-domain-messenger-bindings \
cannon-mips \ cannon-mips \
...@@ -130,6 +131,9 @@ l1-blocknumber-bindings: compile ...@@ -130,6 +131,9 @@ l1-blocknumber-bindings: compile
dispute-game-factory-bindings: compile dispute-game-factory-bindings: compile
./gen_bindings.sh contracts/dispute/DisputeGameFactory.sol:DisputeGameFactory $(pkg) ./gen_bindings.sh contracts/dispute/DisputeGameFactory.sol:DisputeGameFactory $(pkg)
fault-dispute-game-bindings: compile
./gen_bindings.sh contracts/dispute/FaultDisputeGame.sol:FaultDisputeGame $(pkg)
standard-bridge-bindings: compile standard-bridge-bindings: compile
./gen_bindings.sh contracts/universal/StandardBridge.sol:StandardBridge $(pkg) ./gen_bindings.sh contracts/universal/StandardBridge.sol:StandardBridge $(pkg)
......
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"errors"
"math/big"
"strings"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
)
// Reference imports to suppress errors if they are not otherwise used.
var (
_ = errors.New
_ = big.NewInt
_ = strings.NewReader
_ = ethereum.NotFound
_ = bind.Bind
_ = common.Big1
_ = types.BloomLookup
_ = event.NewSubscription
)
// FaultDisputeGameMetaData contains all meta data concerning the FaultDisputeGame contract.
var FaultDisputeGameMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"Claim\",\"name\":\"_absolutePrestate\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_maxGameDepth\",\"type\":\"uint256\"},{\"internalType\":\"contractIBigStepper\",\"name\":\"_vm\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotDefendRootClaim\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ClaimAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ClockTimeExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GameDepthExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GameNotInProgress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidParent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPrestate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValidStep\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"parentIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"Claim\",\"name\":\"pivot\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"claimant\",\"type\":\"address\"}],\"name\":\"Move\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"enumGameStatus\",\"name\":\"status\",\"type\":\"uint8\"}],\"name\":\"Resolved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ABSOLUTE_PRESTATE\",\"outputs\":[{\"internalType\":\"Claim\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_GAME_DEPTH\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VM\",\"outputs\":[{\"internalType\":\"contractIBigStepper\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_parentIndex\",\"type\":\"uint256\"},{\"internalType\":\"Claim\",\"name\":\"_pivot\",\"type\":\"bytes32\"}],\"name\":\"attack\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bondManager\",\"outputs\":[{\"internalType\":\"contractIBondManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"claimData\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"parentIndex\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"countered\",\"type\":\"bool\"},{\"internalType\":\"Claim\",\"name\":\"claim\",\"type\":\"bytes32\"},{\"internalType\":\"Position\",\"name\":\"position\",\"type\":\"uint128\"},{\"internalType\":\"Clock\",\"name\":\"clock\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimDataLen\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"len_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createdAt\",\"outputs\":[{\"internalType\":\"Timestamp\",\"name\":\"createdAt_\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_parentIndex\",\"type\":\"uint256\"},{\"internalType\":\"Claim\",\"name\":\"_pivot\",\"type\":\"bytes32\"}],\"name\":\"defend\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"extraData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"extraData_\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gameData\",\"outputs\":[{\"internalType\":\"GameType\",\"name\":\"gameType_\",\"type\":\"uint8\"},{\"internalType\":\"Claim\",\"name\":\"rootClaim_\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"extraData_\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gameStart\",\"outputs\":[{\"internalType\":\"Timestamp\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gameType\",\"outputs\":[{\"internalType\":\"GameType\",\"name\":\"gameType_\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2BlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"l2BlockNumber_\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_challengeIndex\",\"type\":\"uint256\"},{\"internalType\":\"Claim\",\"name\":\"_pivot\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"_isAttack\",\"type\":\"bool\"}],\"name\":\"move\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"enumGameStatus\",\"name\":\"status_\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rootClaim\",\"outputs\":[{\"internalType\":\"Claim\",\"name\":\"rootClaim_\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"status\",\"outputs\":[{\"internalType\":\"enumGameStatus\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_stateIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_claimIndex\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_isAttack\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"_stateData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_proof\",\"type\":\"bytes\"}],\"name\":\"step\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
Bin: "0x61014060405234801561001157600080fd5b5060405161204c38038061204c8339810160408190526100309161005b565b6000608081905260a052600260c05260e092909252610100526001600160a01b0316610120526100a1565b60008060006060848603121561007057600080fd5b83516020850151604086015191945092506001600160a01b038116811461009657600080fd5b809150509250925092565b60805160a05160c05160e0516101005161012051611f2b610121600039600081816103aa01526114c30152600081816102c20152818161062a01528181610a7e015281816110e30152818161138f01526113d40152600081816101bd0152611217015260006108660152600061083d015260006108140152611f2b6000f3fe60806040526004361061016a5760003560e01c80638129fc1c116100cb578063bcef3b551161007f578063cf09e0d011610059578063cf09e0d01461049c578063e4c290c4146104bb578063fa24f743146104db57600080fd5b8063bcef3b55146103e8578063c55cd0c714610425578063c6f0308c1461043857600080fd5b80638b85902b116100b05780638b85902b146103585780639293129814610398578063bbdc02db146103cc57600080fd5b80638129fc1c1461032e5780638980e0cc1461034357600080fd5b8063363cc4271161012257806354fd4d501161010757806354fd4d50146102e4578063609d333414610306578063632247ea1461031b57600080fd5b8063363cc427146102515780634778efe8146102b057600080fd5b80632810e1d6116101535780632810e1d6146101ed5780633218b99d1461020257806335fef5671461023c57600080fd5b8063200d2ed21461016f578063266198f9146101ab575b600080fd5b34801561017b57600080fd5b506000546101959068010000000000000000900460ff1681565b6040516101a291906119ff565b60405180910390f35b3480156101b757600080fd5b506101df7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016101a2565b3480156101f957600080fd5b506101956104ff565b34801561020e57600080fd5b506000546102239067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016101a2565b61024f61024a366004611a40565b6107fd565b005b34801561025d57600080fd5b5060005461028b906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101a2565b3480156102bc57600080fd5b506101df7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102f057600080fd5b506102f961080d565b6040516101a29190611adc565b34801561031257600080fd5b506102f96108b0565b61024f610329366004611b0b565b6108c2565b34801561033a57600080fd5b5061024f610e7c565b34801561034f57600080fd5b506001546101df565b34801561036457600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003602001356101df565b3480156103a457600080fd5b5061028b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103d857600080fd5b50604051600081526020016101a2565b3480156103f457600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356101df565b61024f610433366004611a40565b610fbd565b34801561044457600080fd5b50610458610453366004611b40565b610fc9565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a0016101a2565b3480156104a857600080fd5b5060005467ffffffffffffffff16610223565b3480156104c757600080fd5b5061024f6104d6366004611ba2565b61103a565b3480156104e757600080fd5b506104f06115b3565b6040516101a293929190611c36565b60008060005468010000000000000000900460ff166002811115610525576105256119d0565b1461055c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805460009161056c91611c90565b90506fffffffffffffffffffffffffffffffff815b67ffffffffffffffff81101561066a576000600182815481106105a6576105a6611ca7565b60009182526020909120600390910201600281015481547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94909401939192506fffffffffffffffffffffffffffffffff1690640100000000900460ff1615610610575050610581565b600061064e6fffffffffffffffffffffffffffffffff83167f00000000000000000000000000000000000000000000000000000000000000006115f1565b905084811015610662578094508360010195505b505050610581565b50600261072f6001848154811061068357610683611ca7565b60009182526020909120600260039092020101546fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6107399190611d05565b67ffffffffffffffff1615801561076057506fffffffffffffffffffffffffffffffff8114155b1561076e5760029250610773565b600192505b600080548491907fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000008360028111156107b8576107b86119d0565b02179055508260028111156107cf576107cf6119d0565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a2505090565b610809828260006108c2565b5050565b60606108387f00000000000000000000000000000000000000000000000000000000000000006116a6565b6108617f00000000000000000000000000000000000000000000000000000000000000006116a6565b61088a7f00000000000000000000000000000000000000000000000000000000000000006116a6565b60405160200161089c93929190611d2c565b604051602081830303815290604052905090565b60606108bd6020806117e3565b905090565b6000805468010000000000000000900460ff1660028111156108e6576108e66119d0565b1461091d576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82158015610929575080155b15610960576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006001848154811061097557610975611ca7565b60009182526020918290206040805160a0810182526003909302909101805463ffffffff8116845260ff64010000000090910416151593830193909352600180840154918301919091526002909201546fffffffffffffffffffffffffffffffff80821660608401527001000000000000000000000000000000009091041660808201528154909250819086908110610a1057610a10611ca7565b6000918252602082206003909102018054921515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909316929092179091556060820151610a7a906fffffffffffffffffffffffffffffffff1684151760011b90565b90507f0000000000000000000000000000000000000000000000000000000000000000610b39826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161115610b7b576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160009063ffffffff90811614610bdb576001836000015163ffffffff1681548110610baa57610baa611ca7565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608083015160009067ffffffffffffffff1667ffffffffffffffff1642610c14846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610c289190611da2565b610c329190611c90565b905062049d4067ffffffffffffffff82161115610c7b576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421790506000610c9c888660009182526020526040902090565b60008181526002602052604090205490915060ff1615610ce8576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260026020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815160a08101835263ffffffff808f1682529381018581528184018e81526fffffffffffffffffffffffffffffffff808d16606085019081528a82166080860190815286548088018855968a52945160039096027fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf68101805495511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000909616979099169690961793909317909655517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf78401555190518416700100000000000000000000000000000000029316929092177fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8909201919091555133918a918c917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a4505050505050505050565b600080547fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000164267ffffffffffffffff161781556040805160a08101825263ffffffff81526020810192909252600191908101610f017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033590565b815260016020820152604001426fffffffffffffffffffffffffffffffff908116909152825460018181018555600094855260209485902084516003909302018054958501511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090961663ffffffff909316929092179490941781556040830151938101939093556060820151608090920151811670010000000000000000000000000000000002911617600290910155565b610809828260016108c2565b60018181548110610fd957600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b6000805468010000000000000000900460ff16600281111561105e5761105e6119d0565b14611095576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600187815481106110aa576110aa611ca7565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506111097f00000000000000000000000000000000000000000000000000000000000000006001611da2565b6111a5826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16146111e6576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611204836fffffffffffffffffffffffffffffffff1661187a565b67ffffffffffffffff16600003611264577f0000000000000000000000000000000000000000000000000000000000000000915060018b8154811061124b5761124b611ca7565b9060005260206000209060030201600101549050611484565b6000808b156112e65760018e8154811061128057611280611ca7565b906000526020600020906003020160020160009054906101000a90046fffffffffffffffffffffffffffffffff16915060018e815481106112c3576112c3611ca7565b906000526020600020906003020160010154935085905086600101549250611375565b600287015460018089015481549096506fffffffffffffffffffffffffffffffff9092169350908f90811061131d5761131d611ca7565b906000526020600020906003020160020160009054906101000a90046fffffffffffffffffffffffffffffffff16905060018e8154811061136057611360611ca7565b90600052602060002090600302016001015492505b60016113b36fffffffffffffffffffffffffffffffff83167f0000000000000000000000000000000000000000000000000000000000000000611920565b6113bd9190611dba565b6fffffffffffffffffffffffffffffffff166114147f0000000000000000000000000000000000000000000000000000000000000000846fffffffffffffffffffffffffffffffff1661192090919063ffffffff16565b6fffffffffffffffffffffffffffffffff1614158061144a5750838b8b60405161143f929190611deb565b604051809103902014155b15611481576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505b6040517ff8e0cb96000000000000000000000000000000000000000000000000000000008152819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f8e0cb96906114fe908d908d908d908d90600401611e44565b6020604051808303816000875af115801561151d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115419190611e76565b03611578576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505082547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff1664010000000017909255505050505050505050565b6000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560606115ea6108b0565b9050909192565b60008061167e847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b6060816000036116e957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561171357806116fd81611e8f565b915061170c9050600a83611ec7565b91506116ed565b60008167ffffffffffffffff81111561172e5761172e611edb565b6040519080825280601f01601f191660200182016040528015611758576020820181803683370190505b5090505b84156117db5761176d600183611c90565b915061177a600a86611f0a565b611785906030611da2565b60f81b81838151811061179a5761179a611ca7565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506117d4600a86611ec7565b945061175c565b949350505050565b6060600061181a84367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003611da2565b90508267ffffffffffffffff1667ffffffffffffffff81111561183f5761183f611edb565b6040519080825280601f01601f191660200182016040528015611869576020820181803683370190505b509150828160208401375092915050565b600080611907837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000806119ad847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169050808303600180821b0385821b179250505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310611a3a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060408385031215611a5357600080fd5b50508035926020909101359150565b60005b83811015611a7d578181015183820152602001611a65565b83811115611a8c576000848401525b50505050565b60008151808452611aaa816020860160208601611a62565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611aef6020830184611a92565b9392505050565b80358015158114611b0657600080fd5b919050565b600080600060608486031215611b2057600080fd5b8335925060208401359150611b3760408501611af6565b90509250925092565b600060208284031215611b5257600080fd5b5035919050565b60008083601f840112611b6b57600080fd5b50813567ffffffffffffffff811115611b8357600080fd5b602083019150836020828501011115611b9b57600080fd5b9250929050565b600080600080600080600060a0888a031215611bbd57600080fd5b8735965060208801359550611bd460408901611af6565b9450606088013567ffffffffffffffff80821115611bf157600080fd5b611bfd8b838c01611b59565b909650945060808a0135915080821115611c1657600080fd5b50611c238a828b01611b59565b989b979a50959850939692959293505050565b60ff84168152826020820152606060408201526000611c586060830184611a92565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611ca257611ca2611c61565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611d2057611d20611cd6565b92169190910692915050565b60008451611d3e818460208901611a62565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611d7a816001850160208a01611a62565b60019201918201528351611d95816002840160208801611a62565b0160020195945050505050565b60008219821115611db557611db5611c61565b500190565b60006fffffffffffffffffffffffffffffffff83811690831681811015611de357611de3611c61565b039392505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000611e58604083018688611dfb565b8281036020840152611e6b818587611dfb565b979650505050505050565b600060208284031215611e8857600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ec057611ec0611c61565b5060010190565b600082611ed657611ed6611cd6565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082611f1957611f19611cd6565b50069056fea164736f6c634300080f000a",
}
// FaultDisputeGameABI is the input ABI used to generate the binding from.
// Deprecated: Use FaultDisputeGameMetaData.ABI instead.
var FaultDisputeGameABI = FaultDisputeGameMetaData.ABI
// FaultDisputeGameBin is the compiled bytecode used for deploying new contracts.
// Deprecated: Use FaultDisputeGameMetaData.Bin instead.
var FaultDisputeGameBin = FaultDisputeGameMetaData.Bin
// DeployFaultDisputeGame deploys a new Ethereum contract, binding an instance of FaultDisputeGame to it.
func DeployFaultDisputeGame(auth *bind.TransactOpts, backend bind.ContractBackend, _absolutePrestate [32]byte, _maxGameDepth *big.Int, _vm common.Address) (common.Address, *types.Transaction, *FaultDisputeGame, error) {
parsed, err := FaultDisputeGameMetaData.GetAbi()
if err != nil {
return common.Address{}, nil, nil, err
}
if parsed == nil {
return common.Address{}, nil, nil, errors.New("GetABI returned nil")
}
address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(FaultDisputeGameBin), backend, _absolutePrestate, _maxGameDepth, _vm)
if err != nil {
return common.Address{}, nil, nil, err
}
return address, tx, &FaultDisputeGame{FaultDisputeGameCaller: FaultDisputeGameCaller{contract: contract}, FaultDisputeGameTransactor: FaultDisputeGameTransactor{contract: contract}, FaultDisputeGameFilterer: FaultDisputeGameFilterer{contract: contract}}, nil
}
// FaultDisputeGame is an auto generated Go binding around an Ethereum contract.
type FaultDisputeGame struct {
FaultDisputeGameCaller // Read-only binding to the contract
FaultDisputeGameTransactor // Write-only binding to the contract
FaultDisputeGameFilterer // Log filterer for contract events
}
// FaultDisputeGameCaller is an auto generated read-only Go binding around an Ethereum contract.
type FaultDisputeGameCaller struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// FaultDisputeGameTransactor is an auto generated write-only Go binding around an Ethereum contract.
type FaultDisputeGameTransactor struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// FaultDisputeGameFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
type FaultDisputeGameFilterer struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// FaultDisputeGameSession is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type FaultDisputeGameSession struct {
Contract *FaultDisputeGame // Generic contract binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// FaultDisputeGameCallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type FaultDisputeGameCallerSession struct {
Contract *FaultDisputeGameCaller // Generic contract caller binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
}
// FaultDisputeGameTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type FaultDisputeGameTransactorSession struct {
Contract *FaultDisputeGameTransactor // Generic contract transactor binding to set the session for
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// FaultDisputeGameRaw is an auto generated low-level Go binding around an Ethereum contract.
type FaultDisputeGameRaw struct {
Contract *FaultDisputeGame // Generic contract binding to access the raw methods on
}
// FaultDisputeGameCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type FaultDisputeGameCallerRaw struct {
Contract *FaultDisputeGameCaller // Generic read-only contract binding to access the raw methods on
}
// FaultDisputeGameTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type FaultDisputeGameTransactorRaw struct {
Contract *FaultDisputeGameTransactor // Generic write-only contract binding to access the raw methods on
}
// NewFaultDisputeGame creates a new instance of FaultDisputeGame, bound to a specific deployed contract.
func NewFaultDisputeGame(address common.Address, backend bind.ContractBackend) (*FaultDisputeGame, error) {
contract, err := bindFaultDisputeGame(address, backend, backend, backend)
if err != nil {
return nil, err
}
return &FaultDisputeGame{FaultDisputeGameCaller: FaultDisputeGameCaller{contract: contract}, FaultDisputeGameTransactor: FaultDisputeGameTransactor{contract: contract}, FaultDisputeGameFilterer: FaultDisputeGameFilterer{contract: contract}}, nil
}
// NewFaultDisputeGameCaller creates a new read-only instance of FaultDisputeGame, bound to a specific deployed contract.
func NewFaultDisputeGameCaller(address common.Address, caller bind.ContractCaller) (*FaultDisputeGameCaller, error) {
contract, err := bindFaultDisputeGame(address, caller, nil, nil)
if err != nil {
return nil, err
}
return &FaultDisputeGameCaller{contract: contract}, nil
}
// NewFaultDisputeGameTransactor creates a new write-only instance of FaultDisputeGame, bound to a specific deployed contract.
func NewFaultDisputeGameTransactor(address common.Address, transactor bind.ContractTransactor) (*FaultDisputeGameTransactor, error) {
contract, err := bindFaultDisputeGame(address, nil, transactor, nil)
if err != nil {
return nil, err
}
return &FaultDisputeGameTransactor{contract: contract}, nil
}
// NewFaultDisputeGameFilterer creates a new log filterer instance of FaultDisputeGame, bound to a specific deployed contract.
func NewFaultDisputeGameFilterer(address common.Address, filterer bind.ContractFilterer) (*FaultDisputeGameFilterer, error) {
contract, err := bindFaultDisputeGame(address, nil, nil, filterer)
if err != nil {
return nil, err
}
return &FaultDisputeGameFilterer{contract: contract}, nil
}
// bindFaultDisputeGame binds a generic wrapper to an already deployed contract.
func bindFaultDisputeGame(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
parsed, err := abi.JSON(strings.NewReader(FaultDisputeGameABI))
if err != nil {
return nil, err
}
return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_FaultDisputeGame *FaultDisputeGameRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _FaultDisputeGame.Contract.FaultDisputeGameCaller.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_FaultDisputeGame *FaultDisputeGameRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _FaultDisputeGame.Contract.FaultDisputeGameTransactor.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_FaultDisputeGame *FaultDisputeGameRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _FaultDisputeGame.Contract.FaultDisputeGameTransactor.contract.Transact(opts, method, params...)
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_FaultDisputeGame *FaultDisputeGameCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _FaultDisputeGame.Contract.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_FaultDisputeGame *FaultDisputeGameTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _FaultDisputeGame.Contract.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_FaultDisputeGame *FaultDisputeGameTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _FaultDisputeGame.Contract.contract.Transact(opts, method, params...)
}
// ABSOLUTEPRESTATE is a free data retrieval call binding the contract method 0x266198f9.
//
// Solidity: function ABSOLUTE_PRESTATE() view returns(bytes32)
func (_FaultDisputeGame *FaultDisputeGameCaller) ABSOLUTEPRESTATE(opts *bind.CallOpts) ([32]byte, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "ABSOLUTE_PRESTATE")
if err != nil {
return *new([32]byte), err
}
out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
return out0, err
}
// ABSOLUTEPRESTATE is a free data retrieval call binding the contract method 0x266198f9.
//
// Solidity: function ABSOLUTE_PRESTATE() view returns(bytes32)
func (_FaultDisputeGame *FaultDisputeGameSession) ABSOLUTEPRESTATE() ([32]byte, error) {
return _FaultDisputeGame.Contract.ABSOLUTEPRESTATE(&_FaultDisputeGame.CallOpts)
}
// ABSOLUTEPRESTATE is a free data retrieval call binding the contract method 0x266198f9.
//
// Solidity: function ABSOLUTE_PRESTATE() view returns(bytes32)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) ABSOLUTEPRESTATE() ([32]byte, error) {
return _FaultDisputeGame.Contract.ABSOLUTEPRESTATE(&_FaultDisputeGame.CallOpts)
}
// MAXGAMEDEPTH is a free data retrieval call binding the contract method 0x4778efe8.
//
// Solidity: function MAX_GAME_DEPTH() view returns(uint256)
func (_FaultDisputeGame *FaultDisputeGameCaller) MAXGAMEDEPTH(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "MAX_GAME_DEPTH")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// MAXGAMEDEPTH is a free data retrieval call binding the contract method 0x4778efe8.
//
// Solidity: function MAX_GAME_DEPTH() view returns(uint256)
func (_FaultDisputeGame *FaultDisputeGameSession) MAXGAMEDEPTH() (*big.Int, error) {
return _FaultDisputeGame.Contract.MAXGAMEDEPTH(&_FaultDisputeGame.CallOpts)
}
// MAXGAMEDEPTH is a free data retrieval call binding the contract method 0x4778efe8.
//
// Solidity: function MAX_GAME_DEPTH() view returns(uint256)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) MAXGAMEDEPTH() (*big.Int, error) {
return _FaultDisputeGame.Contract.MAXGAMEDEPTH(&_FaultDisputeGame.CallOpts)
}
// VM is a free data retrieval call binding the contract method 0x92931298.
//
// Solidity: function VM() view returns(address)
func (_FaultDisputeGame *FaultDisputeGameCaller) VM(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "VM")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// VM is a free data retrieval call binding the contract method 0x92931298.
//
// Solidity: function VM() view returns(address)
func (_FaultDisputeGame *FaultDisputeGameSession) VM() (common.Address, error) {
return _FaultDisputeGame.Contract.VM(&_FaultDisputeGame.CallOpts)
}
// VM is a free data retrieval call binding the contract method 0x92931298.
//
// Solidity: function VM() view returns(address)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) VM() (common.Address, error) {
return _FaultDisputeGame.Contract.VM(&_FaultDisputeGame.CallOpts)
}
// BondManager is a free data retrieval call binding the contract method 0x363cc427.
//
// Solidity: function bondManager() view returns(address)
func (_FaultDisputeGame *FaultDisputeGameCaller) BondManager(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "bondManager")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// BondManager is a free data retrieval call binding the contract method 0x363cc427.
//
// Solidity: function bondManager() view returns(address)
func (_FaultDisputeGame *FaultDisputeGameSession) BondManager() (common.Address, error) {
return _FaultDisputeGame.Contract.BondManager(&_FaultDisputeGame.CallOpts)
}
// BondManager is a free data retrieval call binding the contract method 0x363cc427.
//
// Solidity: function bondManager() view returns(address)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) BondManager() (common.Address, error) {
return _FaultDisputeGame.Contract.BondManager(&_FaultDisputeGame.CallOpts)
}
// ClaimData is a free data retrieval call binding the contract method 0xc6f0308c.
//
// Solidity: function claimData(uint256 ) view returns(uint32 parentIndex, bool countered, bytes32 claim, uint128 position, uint128 clock)
func (_FaultDisputeGame *FaultDisputeGameCaller) ClaimData(opts *bind.CallOpts, arg0 *big.Int) (struct {
ParentIndex uint32
Countered bool
Claim [32]byte
Position *big.Int
Clock *big.Int
}, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "claimData", arg0)
outstruct := new(struct {
ParentIndex uint32
Countered bool
Claim [32]byte
Position *big.Int
Clock *big.Int
})
if err != nil {
return *outstruct, err
}
outstruct.ParentIndex = *abi.ConvertType(out[0], new(uint32)).(*uint32)
outstruct.Countered = *abi.ConvertType(out[1], new(bool)).(*bool)
outstruct.Claim = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte)
outstruct.Position = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int)
outstruct.Clock = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int)
return *outstruct, err
}
// ClaimData is a free data retrieval call binding the contract method 0xc6f0308c.
//
// Solidity: function claimData(uint256 ) view returns(uint32 parentIndex, bool countered, bytes32 claim, uint128 position, uint128 clock)
func (_FaultDisputeGame *FaultDisputeGameSession) ClaimData(arg0 *big.Int) (struct {
ParentIndex uint32
Countered bool
Claim [32]byte
Position *big.Int
Clock *big.Int
}, error) {
return _FaultDisputeGame.Contract.ClaimData(&_FaultDisputeGame.CallOpts, arg0)
}
// ClaimData is a free data retrieval call binding the contract method 0xc6f0308c.
//
// Solidity: function claimData(uint256 ) view returns(uint32 parentIndex, bool countered, bytes32 claim, uint128 position, uint128 clock)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) ClaimData(arg0 *big.Int) (struct {
ParentIndex uint32
Countered bool
Claim [32]byte
Position *big.Int
Clock *big.Int
}, error) {
return _FaultDisputeGame.Contract.ClaimData(&_FaultDisputeGame.CallOpts, arg0)
}
// ClaimDataLen is a free data retrieval call binding the contract method 0x8980e0cc.
//
// Solidity: function claimDataLen() view returns(uint256 len_)
func (_FaultDisputeGame *FaultDisputeGameCaller) ClaimDataLen(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "claimDataLen")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// ClaimDataLen is a free data retrieval call binding the contract method 0x8980e0cc.
//
// Solidity: function claimDataLen() view returns(uint256 len_)
func (_FaultDisputeGame *FaultDisputeGameSession) ClaimDataLen() (*big.Int, error) {
return _FaultDisputeGame.Contract.ClaimDataLen(&_FaultDisputeGame.CallOpts)
}
// ClaimDataLen is a free data retrieval call binding the contract method 0x8980e0cc.
//
// Solidity: function claimDataLen() view returns(uint256 len_)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) ClaimDataLen() (*big.Int, error) {
return _FaultDisputeGame.Contract.ClaimDataLen(&_FaultDisputeGame.CallOpts)
}
// CreatedAt is a free data retrieval call binding the contract method 0xcf09e0d0.
//
// Solidity: function createdAt() view returns(uint64 createdAt_)
func (_FaultDisputeGame *FaultDisputeGameCaller) CreatedAt(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "createdAt")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// CreatedAt is a free data retrieval call binding the contract method 0xcf09e0d0.
//
// Solidity: function createdAt() view returns(uint64 createdAt_)
func (_FaultDisputeGame *FaultDisputeGameSession) CreatedAt() (uint64, error) {
return _FaultDisputeGame.Contract.CreatedAt(&_FaultDisputeGame.CallOpts)
}
// CreatedAt is a free data retrieval call binding the contract method 0xcf09e0d0.
//
// Solidity: function createdAt() view returns(uint64 createdAt_)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) CreatedAt() (uint64, error) {
return _FaultDisputeGame.Contract.CreatedAt(&_FaultDisputeGame.CallOpts)
}
// ExtraData is a free data retrieval call binding the contract method 0x609d3334.
//
// Solidity: function extraData() pure returns(bytes extraData_)
func (_FaultDisputeGame *FaultDisputeGameCaller) ExtraData(opts *bind.CallOpts) ([]byte, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "extraData")
if err != nil {
return *new([]byte), err
}
out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
return out0, err
}
// ExtraData is a free data retrieval call binding the contract method 0x609d3334.
//
// Solidity: function extraData() pure returns(bytes extraData_)
func (_FaultDisputeGame *FaultDisputeGameSession) ExtraData() ([]byte, error) {
return _FaultDisputeGame.Contract.ExtraData(&_FaultDisputeGame.CallOpts)
}
// ExtraData is a free data retrieval call binding the contract method 0x609d3334.
//
// Solidity: function extraData() pure returns(bytes extraData_)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) ExtraData() ([]byte, error) {
return _FaultDisputeGame.Contract.ExtraData(&_FaultDisputeGame.CallOpts)
}
// GameData is a free data retrieval call binding the contract method 0xfa24f743.
//
// Solidity: function gameData() pure returns(uint8 gameType_, bytes32 rootClaim_, bytes extraData_)
func (_FaultDisputeGame *FaultDisputeGameCaller) GameData(opts *bind.CallOpts) (struct {
GameType uint8
RootClaim [32]byte
ExtraData []byte
}, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "gameData")
outstruct := new(struct {
GameType uint8
RootClaim [32]byte
ExtraData []byte
})
if err != nil {
return *outstruct, err
}
outstruct.GameType = *abi.ConvertType(out[0], new(uint8)).(*uint8)
outstruct.RootClaim = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte)
outstruct.ExtraData = *abi.ConvertType(out[2], new([]byte)).(*[]byte)
return *outstruct, err
}
// GameData is a free data retrieval call binding the contract method 0xfa24f743.
//
// Solidity: function gameData() pure returns(uint8 gameType_, bytes32 rootClaim_, bytes extraData_)
func (_FaultDisputeGame *FaultDisputeGameSession) GameData() (struct {
GameType uint8
RootClaim [32]byte
ExtraData []byte
}, error) {
return _FaultDisputeGame.Contract.GameData(&_FaultDisputeGame.CallOpts)
}
// GameData is a free data retrieval call binding the contract method 0xfa24f743.
//
// Solidity: function gameData() pure returns(uint8 gameType_, bytes32 rootClaim_, bytes extraData_)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) GameData() (struct {
GameType uint8
RootClaim [32]byte
ExtraData []byte
}, error) {
return _FaultDisputeGame.Contract.GameData(&_FaultDisputeGame.CallOpts)
}
// GameStart is a free data retrieval call binding the contract method 0x3218b99d.
//
// Solidity: function gameStart() view returns(uint64)
func (_FaultDisputeGame *FaultDisputeGameCaller) GameStart(opts *bind.CallOpts) (uint64, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "gameStart")
if err != nil {
return *new(uint64), err
}
out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)
return out0, err
}
// GameStart is a free data retrieval call binding the contract method 0x3218b99d.
//
// Solidity: function gameStart() view returns(uint64)
func (_FaultDisputeGame *FaultDisputeGameSession) GameStart() (uint64, error) {
return _FaultDisputeGame.Contract.GameStart(&_FaultDisputeGame.CallOpts)
}
// GameStart is a free data retrieval call binding the contract method 0x3218b99d.
//
// Solidity: function gameStart() view returns(uint64)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) GameStart() (uint64, error) {
return _FaultDisputeGame.Contract.GameStart(&_FaultDisputeGame.CallOpts)
}
// GameType is a free data retrieval call binding the contract method 0xbbdc02db.
//
// Solidity: function gameType() pure returns(uint8 gameType_)
func (_FaultDisputeGame *FaultDisputeGameCaller) GameType(opts *bind.CallOpts) (uint8, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "gameType")
if err != nil {
return *new(uint8), err
}
out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
return out0, err
}
// GameType is a free data retrieval call binding the contract method 0xbbdc02db.
//
// Solidity: function gameType() pure returns(uint8 gameType_)
func (_FaultDisputeGame *FaultDisputeGameSession) GameType() (uint8, error) {
return _FaultDisputeGame.Contract.GameType(&_FaultDisputeGame.CallOpts)
}
// GameType is a free data retrieval call binding the contract method 0xbbdc02db.
//
// Solidity: function gameType() pure returns(uint8 gameType_)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) GameType() (uint8, error) {
return _FaultDisputeGame.Contract.GameType(&_FaultDisputeGame.CallOpts)
}
// L2BlockNumber is a free data retrieval call binding the contract method 0x8b85902b.
//
// Solidity: function l2BlockNumber() pure returns(uint256 l2BlockNumber_)
func (_FaultDisputeGame *FaultDisputeGameCaller) L2BlockNumber(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "l2BlockNumber")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// L2BlockNumber is a free data retrieval call binding the contract method 0x8b85902b.
//
// Solidity: function l2BlockNumber() pure returns(uint256 l2BlockNumber_)
func (_FaultDisputeGame *FaultDisputeGameSession) L2BlockNumber() (*big.Int, error) {
return _FaultDisputeGame.Contract.L2BlockNumber(&_FaultDisputeGame.CallOpts)
}
// L2BlockNumber is a free data retrieval call binding the contract method 0x8b85902b.
//
// Solidity: function l2BlockNumber() pure returns(uint256 l2BlockNumber_)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) L2BlockNumber() (*big.Int, error) {
return _FaultDisputeGame.Contract.L2BlockNumber(&_FaultDisputeGame.CallOpts)
}
// RootClaim is a free data retrieval call binding the contract method 0xbcef3b55.
//
// Solidity: function rootClaim() pure returns(bytes32 rootClaim_)
func (_FaultDisputeGame *FaultDisputeGameCaller) RootClaim(opts *bind.CallOpts) ([32]byte, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "rootClaim")
if err != nil {
return *new([32]byte), err
}
out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
return out0, err
}
// RootClaim is a free data retrieval call binding the contract method 0xbcef3b55.
//
// Solidity: function rootClaim() pure returns(bytes32 rootClaim_)
func (_FaultDisputeGame *FaultDisputeGameSession) RootClaim() ([32]byte, error) {
return _FaultDisputeGame.Contract.RootClaim(&_FaultDisputeGame.CallOpts)
}
// RootClaim is a free data retrieval call binding the contract method 0xbcef3b55.
//
// Solidity: function rootClaim() pure returns(bytes32 rootClaim_)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) RootClaim() ([32]byte, error) {
return _FaultDisputeGame.Contract.RootClaim(&_FaultDisputeGame.CallOpts)
}
// Status is a free data retrieval call binding the contract method 0x200d2ed2.
//
// Solidity: function status() view returns(uint8)
func (_FaultDisputeGame *FaultDisputeGameCaller) Status(opts *bind.CallOpts) (uint8, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "status")
if err != nil {
return *new(uint8), err
}
out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
return out0, err
}
// Status is a free data retrieval call binding the contract method 0x200d2ed2.
//
// Solidity: function status() view returns(uint8)
func (_FaultDisputeGame *FaultDisputeGameSession) Status() (uint8, error) {
return _FaultDisputeGame.Contract.Status(&_FaultDisputeGame.CallOpts)
}
// Status is a free data retrieval call binding the contract method 0x200d2ed2.
//
// Solidity: function status() view returns(uint8)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) Status() (uint8, error) {
return _FaultDisputeGame.Contract.Status(&_FaultDisputeGame.CallOpts)
}
// Version is a free data retrieval call binding the contract method 0x54fd4d50.
//
// Solidity: function version() view returns(string)
func (_FaultDisputeGame *FaultDisputeGameCaller) Version(opts *bind.CallOpts) (string, error) {
var out []interface{}
err := _FaultDisputeGame.contract.Call(opts, &out, "version")
if err != nil {
return *new(string), err
}
out0 := *abi.ConvertType(out[0], new(string)).(*string)
return out0, err
}
// Version is a free data retrieval call binding the contract method 0x54fd4d50.
//
// Solidity: function version() view returns(string)
func (_FaultDisputeGame *FaultDisputeGameSession) Version() (string, error) {
return _FaultDisputeGame.Contract.Version(&_FaultDisputeGame.CallOpts)
}
// Version is a free data retrieval call binding the contract method 0x54fd4d50.
//
// Solidity: function version() view returns(string)
func (_FaultDisputeGame *FaultDisputeGameCallerSession) Version() (string, error) {
return _FaultDisputeGame.Contract.Version(&_FaultDisputeGame.CallOpts)
}
// Attack is a paid mutator transaction binding the contract method 0xc55cd0c7.
//
// Solidity: function attack(uint256 _parentIndex, bytes32 _pivot) payable returns()
func (_FaultDisputeGame *FaultDisputeGameTransactor) Attack(opts *bind.TransactOpts, _parentIndex *big.Int, _pivot [32]byte) (*types.Transaction, error) {
return _FaultDisputeGame.contract.Transact(opts, "attack", _parentIndex, _pivot)
}
// Attack is a paid mutator transaction binding the contract method 0xc55cd0c7.
//
// Solidity: function attack(uint256 _parentIndex, bytes32 _pivot) payable returns()
func (_FaultDisputeGame *FaultDisputeGameSession) Attack(_parentIndex *big.Int, _pivot [32]byte) (*types.Transaction, error) {
return _FaultDisputeGame.Contract.Attack(&_FaultDisputeGame.TransactOpts, _parentIndex, _pivot)
}
// Attack is a paid mutator transaction binding the contract method 0xc55cd0c7.
//
// Solidity: function attack(uint256 _parentIndex, bytes32 _pivot) payable returns()
func (_FaultDisputeGame *FaultDisputeGameTransactorSession) Attack(_parentIndex *big.Int, _pivot [32]byte) (*types.Transaction, error) {
return _FaultDisputeGame.Contract.Attack(&_FaultDisputeGame.TransactOpts, _parentIndex, _pivot)
}
// Defend is a paid mutator transaction binding the contract method 0x35fef567.
//
// Solidity: function defend(uint256 _parentIndex, bytes32 _pivot) payable returns()
func (_FaultDisputeGame *FaultDisputeGameTransactor) Defend(opts *bind.TransactOpts, _parentIndex *big.Int, _pivot [32]byte) (*types.Transaction, error) {
return _FaultDisputeGame.contract.Transact(opts, "defend", _parentIndex, _pivot)
}
// Defend is a paid mutator transaction binding the contract method 0x35fef567.
//
// Solidity: function defend(uint256 _parentIndex, bytes32 _pivot) payable returns()
func (_FaultDisputeGame *FaultDisputeGameSession) Defend(_parentIndex *big.Int, _pivot [32]byte) (*types.Transaction, error) {
return _FaultDisputeGame.Contract.Defend(&_FaultDisputeGame.TransactOpts, _parentIndex, _pivot)
}
// Defend is a paid mutator transaction binding the contract method 0x35fef567.
//
// Solidity: function defend(uint256 _parentIndex, bytes32 _pivot) payable returns()
func (_FaultDisputeGame *FaultDisputeGameTransactorSession) Defend(_parentIndex *big.Int, _pivot [32]byte) (*types.Transaction, error) {
return _FaultDisputeGame.Contract.Defend(&_FaultDisputeGame.TransactOpts, _parentIndex, _pivot)
}
// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c.
//
// Solidity: function initialize() returns()
func (_FaultDisputeGame *FaultDisputeGameTransactor) Initialize(opts *bind.TransactOpts) (*types.Transaction, error) {
return _FaultDisputeGame.contract.Transact(opts, "initialize")
}
// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c.
//
// Solidity: function initialize() returns()
func (_FaultDisputeGame *FaultDisputeGameSession) Initialize() (*types.Transaction, error) {
return _FaultDisputeGame.Contract.Initialize(&_FaultDisputeGame.TransactOpts)
}
// Initialize is a paid mutator transaction binding the contract method 0x8129fc1c.
//
// Solidity: function initialize() returns()
func (_FaultDisputeGame *FaultDisputeGameTransactorSession) Initialize() (*types.Transaction, error) {
return _FaultDisputeGame.Contract.Initialize(&_FaultDisputeGame.TransactOpts)
}
// Move is a paid mutator transaction binding the contract method 0x632247ea.
//
// Solidity: function move(uint256 _challengeIndex, bytes32 _pivot, bool _isAttack) payable returns()
func (_FaultDisputeGame *FaultDisputeGameTransactor) Move(opts *bind.TransactOpts, _challengeIndex *big.Int, _pivot [32]byte, _isAttack bool) (*types.Transaction, error) {
return _FaultDisputeGame.contract.Transact(opts, "move", _challengeIndex, _pivot, _isAttack)
}
// Move is a paid mutator transaction binding the contract method 0x632247ea.
//
// Solidity: function move(uint256 _challengeIndex, bytes32 _pivot, bool _isAttack) payable returns()
func (_FaultDisputeGame *FaultDisputeGameSession) Move(_challengeIndex *big.Int, _pivot [32]byte, _isAttack bool) (*types.Transaction, error) {
return _FaultDisputeGame.Contract.Move(&_FaultDisputeGame.TransactOpts, _challengeIndex, _pivot, _isAttack)
}
// Move is a paid mutator transaction binding the contract method 0x632247ea.
//
// Solidity: function move(uint256 _challengeIndex, bytes32 _pivot, bool _isAttack) payable returns()
func (_FaultDisputeGame *FaultDisputeGameTransactorSession) Move(_challengeIndex *big.Int, _pivot [32]byte, _isAttack bool) (*types.Transaction, error) {
return _FaultDisputeGame.Contract.Move(&_FaultDisputeGame.TransactOpts, _challengeIndex, _pivot, _isAttack)
}
// Resolve is a paid mutator transaction binding the contract method 0x2810e1d6.
//
// Solidity: function resolve() returns(uint8 status_)
func (_FaultDisputeGame *FaultDisputeGameTransactor) Resolve(opts *bind.TransactOpts) (*types.Transaction, error) {
return _FaultDisputeGame.contract.Transact(opts, "resolve")
}
// Resolve is a paid mutator transaction binding the contract method 0x2810e1d6.
//
// Solidity: function resolve() returns(uint8 status_)
func (_FaultDisputeGame *FaultDisputeGameSession) Resolve() (*types.Transaction, error) {
return _FaultDisputeGame.Contract.Resolve(&_FaultDisputeGame.TransactOpts)
}
// Resolve is a paid mutator transaction binding the contract method 0x2810e1d6.
//
// Solidity: function resolve() returns(uint8 status_)
func (_FaultDisputeGame *FaultDisputeGameTransactorSession) Resolve() (*types.Transaction, error) {
return _FaultDisputeGame.Contract.Resolve(&_FaultDisputeGame.TransactOpts)
}
// Step is a paid mutator transaction binding the contract method 0xe4c290c4.
//
// Solidity: function step(uint256 _stateIndex, uint256 _claimIndex, bool _isAttack, bytes _stateData, bytes _proof) returns()
func (_FaultDisputeGame *FaultDisputeGameTransactor) Step(opts *bind.TransactOpts, _stateIndex *big.Int, _claimIndex *big.Int, _isAttack bool, _stateData []byte, _proof []byte) (*types.Transaction, error) {
return _FaultDisputeGame.contract.Transact(opts, "step", _stateIndex, _claimIndex, _isAttack, _stateData, _proof)
}
// Step is a paid mutator transaction binding the contract method 0xe4c290c4.
//
// Solidity: function step(uint256 _stateIndex, uint256 _claimIndex, bool _isAttack, bytes _stateData, bytes _proof) returns()
func (_FaultDisputeGame *FaultDisputeGameSession) Step(_stateIndex *big.Int, _claimIndex *big.Int, _isAttack bool, _stateData []byte, _proof []byte) (*types.Transaction, error) {
return _FaultDisputeGame.Contract.Step(&_FaultDisputeGame.TransactOpts, _stateIndex, _claimIndex, _isAttack, _stateData, _proof)
}
// Step is a paid mutator transaction binding the contract method 0xe4c290c4.
//
// Solidity: function step(uint256 _stateIndex, uint256 _claimIndex, bool _isAttack, bytes _stateData, bytes _proof) returns()
func (_FaultDisputeGame *FaultDisputeGameTransactorSession) Step(_stateIndex *big.Int, _claimIndex *big.Int, _isAttack bool, _stateData []byte, _proof []byte) (*types.Transaction, error) {
return _FaultDisputeGame.Contract.Step(&_FaultDisputeGame.TransactOpts, _stateIndex, _claimIndex, _isAttack, _stateData, _proof)
}
// FaultDisputeGameMoveIterator is returned from FilterMove and is used to iterate over the raw logs and unpacked data for Move events raised by the FaultDisputeGame contract.
type FaultDisputeGameMoveIterator struct {
Event *FaultDisputeGameMove // 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 *FaultDisputeGameMoveIterator) 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(FaultDisputeGameMove)
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(FaultDisputeGameMove)
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 *FaultDisputeGameMoveIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *FaultDisputeGameMoveIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// FaultDisputeGameMove represents a Move event raised by the FaultDisputeGame contract.
type FaultDisputeGameMove struct {
ParentIndex *big.Int
Pivot [32]byte
Claimant common.Address
Raw types.Log // Blockchain specific contextual infos
}
// FilterMove is a free log retrieval operation binding the contract event 0x9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be.
//
// Solidity: event Move(uint256 indexed parentIndex, bytes32 indexed pivot, address indexed claimant)
func (_FaultDisputeGame *FaultDisputeGameFilterer) FilterMove(opts *bind.FilterOpts, parentIndex []*big.Int, pivot [][32]byte, claimant []common.Address) (*FaultDisputeGameMoveIterator, error) {
var parentIndexRule []interface{}
for _, parentIndexItem := range parentIndex {
parentIndexRule = append(parentIndexRule, parentIndexItem)
}
var pivotRule []interface{}
for _, pivotItem := range pivot {
pivotRule = append(pivotRule, pivotItem)
}
var claimantRule []interface{}
for _, claimantItem := range claimant {
claimantRule = append(claimantRule, claimantItem)
}
logs, sub, err := _FaultDisputeGame.contract.FilterLogs(opts, "Move", parentIndexRule, pivotRule, claimantRule)
if err != nil {
return nil, err
}
return &FaultDisputeGameMoveIterator{contract: _FaultDisputeGame.contract, event: "Move", logs: logs, sub: sub}, nil
}
// WatchMove is a free log subscription operation binding the contract event 0x9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be.
//
// Solidity: event Move(uint256 indexed parentIndex, bytes32 indexed pivot, address indexed claimant)
func (_FaultDisputeGame *FaultDisputeGameFilterer) WatchMove(opts *bind.WatchOpts, sink chan<- *FaultDisputeGameMove, parentIndex []*big.Int, pivot [][32]byte, claimant []common.Address) (event.Subscription, error) {
var parentIndexRule []interface{}
for _, parentIndexItem := range parentIndex {
parentIndexRule = append(parentIndexRule, parentIndexItem)
}
var pivotRule []interface{}
for _, pivotItem := range pivot {
pivotRule = append(pivotRule, pivotItem)
}
var claimantRule []interface{}
for _, claimantItem := range claimant {
claimantRule = append(claimantRule, claimantItem)
}
logs, sub, err := _FaultDisputeGame.contract.WatchLogs(opts, "Move", parentIndexRule, pivotRule, claimantRule)
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(FaultDisputeGameMove)
if err := _FaultDisputeGame.contract.UnpackLog(event, "Move", 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
}
// ParseMove is a log parse operation binding the contract event 0x9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be.
//
// Solidity: event Move(uint256 indexed parentIndex, bytes32 indexed pivot, address indexed claimant)
func (_FaultDisputeGame *FaultDisputeGameFilterer) ParseMove(log types.Log) (*FaultDisputeGameMove, error) {
event := new(FaultDisputeGameMove)
if err := _FaultDisputeGame.contract.UnpackLog(event, "Move", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// FaultDisputeGameResolvedIterator is returned from FilterResolved and is used to iterate over the raw logs and unpacked data for Resolved events raised by the FaultDisputeGame contract.
type FaultDisputeGameResolvedIterator struct {
Event *FaultDisputeGameResolved // 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 *FaultDisputeGameResolvedIterator) 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(FaultDisputeGameResolved)
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(FaultDisputeGameResolved)
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 *FaultDisputeGameResolvedIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *FaultDisputeGameResolvedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// FaultDisputeGameResolved represents a Resolved event raised by the FaultDisputeGame contract.
type FaultDisputeGameResolved struct {
Status uint8
Raw types.Log // Blockchain specific contextual infos
}
// FilterResolved is a free log retrieval operation binding the contract event 0x5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da60.
//
// Solidity: event Resolved(uint8 indexed status)
func (_FaultDisputeGame *FaultDisputeGameFilterer) FilterResolved(opts *bind.FilterOpts, status []uint8) (*FaultDisputeGameResolvedIterator, error) {
var statusRule []interface{}
for _, statusItem := range status {
statusRule = append(statusRule, statusItem)
}
logs, sub, err := _FaultDisputeGame.contract.FilterLogs(opts, "Resolved", statusRule)
if err != nil {
return nil, err
}
return &FaultDisputeGameResolvedIterator{contract: _FaultDisputeGame.contract, event: "Resolved", logs: logs, sub: sub}, nil
}
// WatchResolved is a free log subscription operation binding the contract event 0x5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da60.
//
// Solidity: event Resolved(uint8 indexed status)
func (_FaultDisputeGame *FaultDisputeGameFilterer) WatchResolved(opts *bind.WatchOpts, sink chan<- *FaultDisputeGameResolved, status []uint8) (event.Subscription, error) {
var statusRule []interface{}
for _, statusItem := range status {
statusRule = append(statusRule, statusItem)
}
logs, sub, err := _FaultDisputeGame.contract.WatchLogs(opts, "Resolved", statusRule)
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(FaultDisputeGameResolved)
if err := _FaultDisputeGame.contract.UnpackLog(event, "Resolved", 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
}
// ParseResolved is a log parse operation binding the contract event 0x5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da60.
//
// Solidity: event Resolved(uint8 indexed status)
func (_FaultDisputeGame *FaultDisputeGameFilterer) ParseResolved(log types.Log) (*FaultDisputeGameResolved, error) {
event := new(FaultDisputeGameResolved)
if err := _FaultDisputeGame.contract.UnpackLog(event, "Resolved", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
package main
import (
"bytes"
"context"
"errors"
"fmt"
"math/big"
"os"
"golang.org/x/sync/errgroup"
"github.com/mattn/go-isatty"
"github.com/urfave/cli/v2"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/util"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
)
var defaultCrossDomainMessageSender = common.HexToAddress("0x000000000000000000000000000000000000dead")
// Default script for checking that L2 has been configured correctly. This should be extended in the future
// to pull in L1 deploy artifacts and assert that the L2 state is consistent with the L1 state.
func main() {
log.Root().SetHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(isatty.IsTerminal(os.Stderr.Fd()))))
flags := []cli.Flag{}
flags = append(flags, util.ClientsFlags...)
flags = append(flags, util.AddressesFlags...)
app := &cli.App{
Name: "check-l2",
Usage: "Check that an OP Stack L2 has been configured correctly",
Flags: flags,
Action: func(ctx *cli.Context) error {
clients, err := util.NewClients(ctx)
if err != nil {
return err
}
log.Info("Checking predeploy proxy config")
g := new(errgroup.Group)
// Check that all proxies are configured correctly
// Do this in parallel but not too quickly to allow for
// querying against rate limiting RPC backends
count := uint64(2048)
for i := uint64(0); i < count; i++ {
i := i
if i%4 == 0 {
log.Info("Checking proxy", "index", i, "total", count)
if err := g.Wait(); err != nil {
return err
}
}
g.Go(func() error {
return checkPredeploy(clients.L2Client, i)
})
}
if err := g.Wait(); err != nil {
return err
}
log.Info("All predeploy proxies are set correctly")
// Check that all of the defined predeploys are set up correctly
for name, addr := range predeploys.Predeploys {
log.Info("Checking predeploy", "name", name, "address", addr.Hex())
if err := checkPredeployConfig(clients.L2Client, name); err != nil {
return err
}
}
return nil
},
}
if err := app.Run(os.Args); err != nil {
log.Crit("error indexing state", "err", err)
}
}
// checkPredeployConfig checks that the defined predeploys are configured correctly
func checkPredeployConfig(client *ethclient.Client, name string) error {
predeploy := predeploys.Predeploys[name]
if predeploy == nil {
return fmt.Errorf("unknown predeploy %s", name)
}
p := *predeploy
g := new(errgroup.Group)
if predeploys.IsProxied(p) {
// Check that an implementation is set. If the implementation has been upgraded,
// it will be considered non-standard. Ensure that there is code set at the implementation.
g.Go(func() error {
impl, err := getEIP1967ImplementationAddress(client, p)
if err != nil {
return err
}
log.Info(name, "implementation", impl.Hex())
standardImpl, err := genesis.AddressToCodeNamespace(p)
if err != nil {
return err
}
if impl != standardImpl {
log.Warn("%s does not have the standard implementation", name)
}
implCode, err := client.CodeAt(context.Background(), impl, nil)
if err != nil {
return err
}
if len(implCode) == 0 {
return fmt.Errorf("%s implementation is not deployed", name)
}
return nil
})
// Ensure that the code is set to the proxy bytecode as expected
g.Go(func() error {
proxyCode, err := client.CodeAt(context.Background(), p, nil)
if err != nil {
return err
}
proxy, err := bindings.GetDeployedBytecode("Proxy")
if err != nil {
return err
}
if !bytes.Equal(proxyCode, proxy) {
return fmt.Errorf("%s does not have the standard proxy code", name)
}
return nil
})
}
// Check the predeploy specific config is correct
g.Go(func() error {
switch p {
case predeploys.LegacyMessagePasserAddr:
if err := checkLegacyMessagePasser(p, client); err != nil {
return err
}
case predeploys.DeployerWhitelistAddr:
if err := checkDeployerWhitelist(p, client); err != nil {
return err
}
case predeploys.L2CrossDomainMessengerAddr:
if err := checkL2CrossDomainMessenger(p, client); err != nil {
return err
}
case predeploys.GasPriceOracleAddr:
if err := checkGasPriceOracle(p, client); err != nil {
return err
}
case predeploys.L2StandardBridgeAddr:
if err := checkL2StandardBridge(p, client); err != nil {
return err
}
case predeploys.SequencerFeeVaultAddr:
if err := checkSequencerFeeVault(p, client); err != nil {
return err
}
case predeploys.OptimismMintableERC20FactoryAddr:
if err := checkOptimismMintableERC20Factory(p, client); err != nil {
return err
}
case predeploys.L1BlockNumberAddr:
if err := checkL1BlockNumber(p, client); err != nil {
return err
}
case predeploys.L1BlockAddr:
if err := checkL1Block(p, client); err != nil {
return err
}
case predeploys.WETH9Addr:
if err := checkWETH9(p, client); err != nil {
return err
}
case predeploys.GovernanceTokenAddr:
if err := checkGovernanceToken(p, client); err != nil {
return err
}
case predeploys.L2ERC721BridgeAddr:
if err := checkL2ERC721Bridge(p, client); err != nil {
return err
}
case predeploys.OptimismMintableERC721FactoryAddr:
if err := checkOptimismMintableERC721Factory(p, client); err != nil {
return err
}
case predeploys.ProxyAdminAddr:
if err := checkProxyAdmin(p, client); err != nil {
return err
}
case predeploys.BaseFeeVaultAddr:
if err := checkBaseFeeVault(p, client); err != nil {
return err
}
case predeploys.L1FeeVaultAddr:
if err := checkL1FeeVault(p, client); err != nil {
return err
}
case predeploys.L2ToL1MessagePasserAddr:
if err := checkL2ToL1MessagePasser(p, client); err != nil {
return err
}
}
return nil
})
if err := g.Wait(); err != nil {
return err
}
return nil
}
func checkL2ToL1MessagePasser(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewL2ToL1MessagePasser(addr, client)
if err != nil {
return err
}
messageVersion, err := contract.MESSAGEVERSION(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2ToL1MessagePasser", "MESSAGE_VERSION", messageVersion)
messageNonce, err := contract.MessageNonce(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2ToL1MessagePasser", "MESSAGE_NONCE", messageNonce)
return nil
}
func checkL1FeeVault(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewL1FeeVault(addr, client)
if err != nil {
return err
}
recipient, err := contract.RECIPIENT(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L1FeeVault", "RECIPIENT", recipient.Hex())
if recipient == (common.Address{}) {
return errors.New("RECIPIENT should not be address(0)")
}
minWithdrawalAmount, err := contract.MINWITHDRAWALAMOUNT(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L1FeeVault", "MIN_WITHDRAWAL_AMOUNT", minWithdrawalAmount)
version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L1FeeVault version", "version", version)
return nil
}
func checkBaseFeeVault(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewBaseFeeVault(addr, client)
if err != nil {
return err
}
recipient, err := contract.RECIPIENT(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("BaseFeeVault", "RECIPIENT", recipient.Hex())
if recipient == (common.Address{}) {
return errors.New("RECIPIENT should not be address(0)")
}
minWithdrawalAmount, err := contract.MINWITHDRAWALAMOUNT(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("BaseFeeVault", "MIN_WITHDRAWAL_AMOUNT", minWithdrawalAmount)
version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("BaseFeeVault version", "version", version)
return nil
}
func checkProxyAdmin(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewProxyAdmin(addr, client)
if err != nil {
return err
}
owner, err := contract.Owner(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("ProxyAdmin", "owner", owner.Hex())
if owner == (common.Address{}) {
return errors.New("ProxyAdmin.owner is zero address")
}
addressManager, err := contract.AddressManager(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("ProxyAdmin", "addressManager", addressManager.Hex())
return nil
}
func checkOptimismMintableERC721Factory(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewOptimismMintableERC721Factory(addr, client)
if err != nil {
return err
}
bridge, err := contract.BRIDGE(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("OptimismMintableERC721Factory", "BRIDGE", bridge.Hex())
if bridge == (common.Address{}) {
return errors.New("OptimismMintableERC721Factory.BRIDGE is zero address")
}
remoteChainID, err := contract.REMOTECHAINID(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("OptimismMintableERC721Factory", "REMOTE_CHAIN_ID", remoteChainID)
version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("OptimismMintableERC721Factory version", "version", version)
return nil
}
func checkL2ERC721Bridge(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewL2ERC721Bridge(addr, client)
if err != nil {
return err
}
messenger, err := contract.MESSENGER(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2ERC721Bridge", "MESSENGER", messenger.Hex())
if messenger == (common.Address{}) {
return errors.New("L2ERC721Bridge.MESSENGER is zero address")
}
otherBridge, err := contract.OTHERBRIDGE(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2ERC721Bridge", "OTHERBRIDGE", otherBridge.Hex())
if otherBridge == (common.Address{}) {
return errors.New("L2ERC721Bridge.OTHERBRIDGE is zero address")
}
version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2ERC721Bridge version", "version", version)
return nil
}
func checkGovernanceToken(addr common.Address, client *ethclient.Client) error {
code, err := client.CodeAt(context.Background(), addr, nil)
if err != nil {
return err
}
if len(code) > 0 {
// This should also check the owner
contract, err := bindings.NewERC20(addr, client)
if err != nil {
return err
}
name, err := contract.Name(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("GovernanceToken", "name", name)
symbol, err := contract.Symbol(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("GovernanceToken", "symbol", symbol)
totalSupply, err := contract.TotalSupply(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("GovernanceToken", "totalSupply", totalSupply)
} else {
log.Info("No code at GovernanceToken")
}
return nil
}
func checkWETH9(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewWETH9(addr, client)
if err != nil {
return err
}
name, err := contract.Name(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("WETH9", "name", name)
if name != "Wrapped Ether" {
return fmt.Errorf("WETH9 name should be 'Wrapped Ether', got %s", name)
}
symbol, err := contract.Symbol(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("WETH9", "symbol", symbol)
if symbol != "WETH" {
return fmt.Errorf("WETH9 symbol should be 'WETH', got %s", symbol)
}
decimals, err := contract.Decimals(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("WETH9", "decimals", decimals)
if decimals != 18 {
return fmt.Errorf("WETH9 decimals should be 18, got %d", decimals)
}
return nil
}
func checkL1Block(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewL1Block(addr, client)
if err != nil {
return err
}
version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L1Block version", "version", version)
return nil
}
func checkL1BlockNumber(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewL1BlockNumber(addr, client)
if err != nil {
return err
}
version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L1BlockNumber version", "version", version)
return nil
}
func checkOptimismMintableERC20Factory(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewOptimismMintableERC20Factory(addr, client)
if err != nil {
return err
}
bridge, err := contract.BRIDGE(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("OptimismMintableERC20Factory", "BRIDGE", bridge.Hex())
if bridge == (common.Address{}) {
return errors.New("OptimismMintableERC20Factory.BRIDGE is zero address")
}
version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("OptimismMintableERC20Factory version", "version", version)
return nil
}
func checkSequencerFeeVault(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewSequencerFeeVault(addr, client)
if err != nil {
return err
}
recipient, err := contract.RECIPIENT(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("SequencerFeeVault", "RECIPIENT", recipient.Hex())
if recipient == (common.Address{}) {
return errors.New("RECIPIENT should not be address(0)")
}
l1FeeWallet, err := contract.L1FeeWallet(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("SequencerFeeVault", "l1FeeWallet", l1FeeWallet.Hex())
minWithdrawalAmount, err := contract.MINWITHDRAWALAMOUNT(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("SequencerFeeVault", "MIN_WITHDRAWAL_AMOUNT", minWithdrawalAmount)
version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("SequencerFeeVault version", "version", version)
return nil
}
func checkL2StandardBridge(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewL2StandardBridge(addr, client)
if err != nil {
return err
}
otherBridge, err := contract.OTHERBRIDGE(&bind.CallOpts{})
if err != nil {
return err
}
if otherBridge == (common.Address{}) {
return errors.New("OTHERBRIDGE should not be address(0)")
}
log.Info("L2StandardBridge", "OTHERBRIDGE", otherBridge.Hex())
messenger, err := contract.MESSENGER(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2StandardBridge", "MESSENGER", messenger.Hex())
if messenger != predeploys.L2CrossDomainMessengerAddr {
return fmt.Errorf("L2StandardBridge MESSENGER should be %s, got %s", predeploys.L2CrossDomainMessengerAddr, messenger)
}
version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2StandardBridge version", "version", version)
return nil
}
func checkGasPriceOracle(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewGasPriceOracle(addr, client)
if err != nil {
return err
}
decimals, err := contract.DECIMALS(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("GasPriceOracle", "DECIMALS", decimals)
if decimals.Cmp(big.NewInt(6)) != 0 {
return fmt.Errorf("GasPriceOracle decimals should be 6, got %v", decimals)
}
version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("GasPriceOracle version", "version", version)
return nil
}
func checkL2CrossDomainMessenger(addr common.Address, client *ethclient.Client) error {
slot, err := client.StorageAt(context.Background(), addr, common.Hash{31: 0xcc}, nil)
if err != nil {
return err
}
if common.BytesToAddress(slot) != defaultCrossDomainMessageSender {
return fmt.Errorf("Expected xDomainMsgSender to be %s, got %s", defaultCrossDomainMessageSender, addr)
}
contract, err := bindings.NewL2CrossDomainMessenger(addr, client)
if err != nil {
return err
}
otherMessenger, err := contract.OTHERMESSENGER(&bind.CallOpts{})
if err != nil {
return err
}
if otherMessenger == (common.Address{}) {
return errors.New("OTHERMESSENGER should not be address(0)")
}
log.Info("L2CrossDomainMessenger", "OTHERMESSENGER", otherMessenger.Hex())
l1CrossDomainMessenger, err := contract.L1CrossDomainMessenger(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2CrossDomainMessenger", "l1CrossDomainMessenger", l1CrossDomainMessenger.Hex())
messageVersion, err := contract.MESSAGEVERSION(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2CrossDomainMessenger", "MESSAGE_VERSION", messageVersion)
minGasCallDataOverhead, err := contract.MINGASCALLDATAOVERHEAD(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2CrossDomainMessenger", "MIN_GAS_CALLDATA_OVERHEAD", minGasCallDataOverhead)
relayConstantOverhead, err := contract.RELAYCONSTANTOVERHEAD(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2CrossDomainMessenger", "RELAY_CONSTANT_OVERHEAD", relayConstantOverhead)
minGasDynamicsOverheadDenominator, err := contract.MINGASDYNAMICOVERHEADDENOMINATOR(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2CrossDomainMessenger", "MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR", minGasDynamicsOverheadDenominator)
minGasDynamicsOverheadNumerator, err := contract.MINGASDYNAMICOVERHEADNUMERATOR(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2CrossDomainMessenger", "MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR", minGasDynamicsOverheadNumerator)
relayCallOverhead, err := contract.RELAYCALLOVERHEAD(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2CrossDomainMessenger", "RELAY_CALL_OVERHEAD", relayCallOverhead)
relayReservedGas, err := contract.RELAYRESERVEDGAS(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2CrossDomainMessenger", "RELAY_RESERVED_GAS", relayReservedGas)
relayGasCheckBuffer, err := contract.RELAYGASCHECKBUFFER(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2CrossDomainMessenger", "RELAY_GAS_CHECK_BUFFER", relayGasCheckBuffer)
version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("L2CrossDomainMessenger version", "version", version)
return nil
}
func checkLegacyMessagePasser(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewLegacyMessagePasser(addr, client)
if err != nil {
return err
}
version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("LegacyMessagePasser version", "version", version)
return nil
}
func checkDeployerWhitelist(addr common.Address, client *ethclient.Client) error {
contract, err := bindings.NewDeployerWhitelist(addr, client)
if err != nil {
return err
}
owner, err := contract.Owner(&bind.CallOpts{})
if err != nil {
return err
}
if owner != (common.Address{}) {
return fmt.Errorf("DeployerWhitelist owner should be set to address(0)")
}
version, err := contract.Version(&bind.CallOpts{})
if err != nil {
return err
}
log.Info("DeployerWhitelist version", "version", version)
return nil
}
func getEIP1967AdminAddress(client *ethclient.Client, addr common.Address) (common.Address, error) {
slot, err := client.StorageAt(context.Background(), addr, util.EIP1967AdminSlot, nil)
if err != nil {
return common.Address{}, err
}
admin := common.BytesToAddress(slot)
return admin, nil
}
func getEIP1967ImplementationAddress(client *ethclient.Client, addr common.Address) (common.Address, error) {
slot, err := client.StorageAt(context.Background(), addr, util.EIP1967ImplementationSlot, nil)
if err != nil {
return common.Address{}, err
}
impl := common.BytesToAddress(slot)
return impl, nil
}
// checkPredeploy ensures that the predeploy at index i has the correct proxy admin set
func checkPredeploy(client *ethclient.Client, i uint64) error {
bigAddr := new(big.Int).Or(genesis.BigL2PredeployNamespace, new(big.Int).SetUint64(i))
addr := common.BigToAddress(bigAddr)
if !predeploys.IsProxied(addr) {
return nil
}
admin, err := getEIP1967AdminAddress(client, addr)
if err != nil {
return err
}
if admin != predeploys.ProxyAdminAddr {
return fmt.Errorf("%s does not have correct proxy admin set", addr)
}
return nil
}
...@@ -21,7 +21,7 @@ var ( ...@@ -21,7 +21,7 @@ var (
// l1PredeployNamespace represents the namespace of L1 predeploys // l1PredeployNamespace represents the namespace of L1 predeploys
l1PredeployNamespace = common.HexToAddress("0x6900000000000000000000000000000000000000") l1PredeployNamespace = common.HexToAddress("0x6900000000000000000000000000000000000000")
// bigL2PredeployNamespace represents the predeploy namespace as a big.Int // bigL2PredeployNamespace represents the predeploy namespace as a big.Int
bigL2PredeployNamespace = new(big.Int).SetBytes(l2PredeployNamespace.Bytes()) BigL2PredeployNamespace = new(big.Int).SetBytes(l2PredeployNamespace.Bytes())
// bigL1PredeployNamespace represents the predeploy namespace as a big.Int // bigL1PredeployNamespace represents the predeploy namespace as a big.Int
bigL1PredeployNamespace = new(big.Int).SetBytes(l1PredeployNamespace.Bytes()) bigL1PredeployNamespace = new(big.Int).SetBytes(l1PredeployNamespace.Bytes())
// bigCodeNamespace represents the predeploy namespace as a big.Int // bigCodeNamespace represents the predeploy namespace as a big.Int
......
...@@ -36,7 +36,7 @@ func BuildL2Genesis(config *DeployConfig, l1StartBlock *types.Block) (*core.Gene ...@@ -36,7 +36,7 @@ func BuildL2Genesis(config *DeployConfig, l1StartBlock *types.Block) (*core.Gene
} }
// Set up the proxies // Set up the proxies
err = setProxies(db, predeploys.ProxyAdminAddr, bigL2PredeployNamespace, 2048) err = setProxies(db, predeploys.ProxyAdminAddr, BigL2PredeployNamespace, 2048)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
package util
import (
"context"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient/gethclient"
"github.com/ethereum/go-ethereum/rpc"
"github.com/urfave/cli/v2"
)
var (
// EIP1976ImplementationSlot
EIP1967ImplementationSlot = common.HexToHash("0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc")
// EIP1967AdminSlot
EIP1967AdminSlot = common.HexToHash("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103")
)
// clients represents a set of initialized RPC clients
type Clients struct {
L1Client *ethclient.Client
L2Client *ethclient.Client
L1RpcClient *rpc.Client
L2RpcClient *rpc.Client
L1GethClient *gethclient.Client
L2GethClient *gethclient.Client
}
// NewClients will create new RPC clients from a CLI context
func NewClients(ctx *cli.Context) (*Clients, error) {
clients := Clients{}
l1RpcURL := ctx.String("l1-rpc-url")
if l1RpcURL != "" {
l1Client, l1RpcClient, l1GethClient, err := newClients(l1RpcURL)
if err != nil {
return nil, err
}
clients.L1Client = l1Client
clients.L1RpcClient = l1RpcClient
clients.L1GethClient = l1GethClient
}
l2RpcURL := ctx.String("l2-rpc-url")
if l2RpcURL != "" {
l2Client, l2RpcClient, l2GethClient, err := newClients(l2RpcURL)
if err != nil {
return nil, err
}
clients.L2Client = l2Client
clients.L2RpcClient = l2RpcClient
clients.L2GethClient = l2GethClient
}
return &clients, nil
}
// newClients will create new clients from a given URL
func newClients(url string) (*ethclient.Client, *rpc.Client, *gethclient.Client, error) {
ethClient, err := ethclient.Dial(url)
if err != nil {
return nil, nil, nil, fmt.Errorf("cannot dial ethclient: %w", err)
}
rpcClient, err := rpc.DialContext(context.Background(), url)
if err != nil {
return nil, nil, nil, fmt.Errorf("cannot dial rpc client: %w", err)
}
return ethClient, rpcClient, gethclient.New(rpcClient), nil
}
// ClientsFlags represent the flags associated with creating RPC clients.
var ClientsFlags = []cli.Flag{
&cli.StringFlag{
Name: "l1-rpc-url",
Required: true,
Usage: "L1 RPC URL",
EnvVars: []string{"L1_RPC_URL"},
},
&cli.StringFlag{
Name: "l2-rpc-url",
Required: true,
Usage: "L2 RPC URL",
EnvVars: []string{"L2_RPC_URL"},
},
}
// Addresses represents the address values of various contracts. The values can
// be easily populated via a [cli.Context].
type Addresses struct {
AddressManager common.Address
OptimismPortal common.Address
L1StandardBridge common.Address
L1CrossDomainMessenger common.Address
CanonicalTransactionChain common.Address
StateCommitmentChain common.Address
}
// AddressesFlags represent the flags associated with address parsing.
var AddressesFlags = []cli.Flag{
&cli.StringFlag{
Name: "address-manager-address",
Usage: "AddressManager address",
EnvVars: []string{"ADDRESS_MANAGER_ADDRESS"},
},
&cli.StringFlag{
Name: "optimism-portal-address",
Usage: "OptimismPortal address",
EnvVars: []string{"OPTIMISM_PORTAL_ADDRESS"},
},
&cli.StringFlag{
Name: "l1-standard-bridge-address",
Usage: "L1StandardBridge address",
EnvVars: []string{"L1_STANDARD_BRIDGE_ADDRESS"},
},
&cli.StringFlag{
Name: "l1-crossdomain-messenger-address",
Usage: "L1CrossDomainMessenger address",
EnvVars: []string{"L1_CROSSDOMAIN_MESSENGER_ADDRESS"},
},
&cli.StringFlag{
Name: "canonical-transaction-chain-address",
Usage: "CanonicalTransactionChain address",
EnvVars: []string{"CANONICAL_TRANSACTION_CHAIN_ADDRESS"},
},
&cli.StringFlag{
Name: "state-commitment-chain-address",
Usage: "StateCommitmentChain address",
EnvVars: []string{"STATE_COMMITMENT_CHAIN_ADDRESS"},
},
}
// NewAddresses populates an Addresses struct given a [cli.Context].
// This is useful for writing scripts that interact with smart contracts.
func NewAddresses(ctx *cli.Context) (*Addresses, error) {
var addresses Addresses
var err error
addresses.AddressManager, err = parseAddress(ctx, "address-manager-address")
if err != nil {
return nil, err
}
addresses.OptimismPortal, err = parseAddress(ctx, "optimism-portal-address")
if err != nil {
return nil, err
}
addresses.L1StandardBridge, err = parseAddress(ctx, "l1-standard-bridge-address")
if err != nil {
return nil, err
}
addresses.L1CrossDomainMessenger, err = parseAddress(ctx, "l1-crossdomain-messenger-address")
if err != nil {
return nil, err
}
addresses.CanonicalTransactionChain, err = parseAddress(ctx, "canonical-transaction-chain-address")
if err != nil {
return nil, err
}
addresses.StateCommitmentChain, err = parseAddress(ctx, "state-commitment-chain-address")
if err != nil {
return nil, err
}
return &addresses, nil
}
// parseAddress will parse a [common.Address] from a [cli.Context] and return
// an error if the configured address is not correct.
func parseAddress(ctx *cli.Context, name string) (common.Address, error) {
value := ctx.String(name)
if value == "" {
return common.Address{}, nil
}
if !common.IsHexAddress(value) {
return common.Address{}, fmt.Errorf("invalid address: %s", value)
}
return common.HexToAddress(value), nil
}
...@@ -2,6 +2,7 @@ package preimage ...@@ -2,6 +2,7 @@ package preimage
import ( import (
"encoding/binary" "encoding/binary"
"encoding/hex"
"fmt" "fmt"
"io" "io"
) )
...@@ -57,7 +58,7 @@ func (o *OracleServer) NextPreimageRequest(getPreimage PreimageGetter) error { ...@@ -57,7 +58,7 @@ func (o *OracleServer) NextPreimageRequest(getPreimage PreimageGetter) error {
} }
value, err := getPreimage(key) value, err := getPreimage(key)
if err != nil { if err != nil {
return fmt.Errorf("failed to serve pre-image %s request: %w", key, err) return fmt.Errorf("failed to serve pre-image %s request: %w", hex.EncodeToString(key[:]), err)
} }
if err := binary.Write(o.rw, binary.BigEndian, uint64(len(value))); err != nil { if err := binary.Write(o.rw, binary.BigEndian, uint64(len(value))); err != nil {
......
...@@ -114,6 +114,7 @@ func Run(l1RpcUrl string, l2RpcUrl string, l2OracleAddr common.Address) error { ...@@ -114,6 +114,7 @@ func Run(l1RpcUrl string, l2RpcUrl string, l2OracleAddr common.Address) error {
}() }()
fmt.Printf("Using temp dir: %s\n", temp) fmt.Printf("Using temp dir: %s\n", temp)
args := []string{ args := []string{
"--log.level", "DEBUG",
"--network", "goerli", "--network", "goerli",
"--exec", "./bin/op-program-client", "--exec", "./bin/op-program-client",
"--datadir", temp, "--datadir", temp,
......
...@@ -32,30 +32,30 @@ DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_revert ...@@ -32,30 +32,30 @@ DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_revert
DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44243) DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44243)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15950) DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15950)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18642) DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18642)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 502842) FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 498826)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 504699) FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 500705)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot:test_resolvesCorrectly_succeeds() (gas: 492706) FaultDisputeGame_ResolvesCorrectly_CorrectRoot:test_resolvesCorrectly_succeeds() (gas: 488169)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 501717) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 497701)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 503574) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 499580)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot:test_resolvesCorrectly_succeeds() (gas: 491581) FaultDisputeGame_ResolvesCorrectly_IncorrectRoot:test_resolvesCorrectly_succeeds() (gas: 487044)
FaultDisputeGame_Test:test_defendRoot_invalidMove_reverts() (gas: 13250) FaultDisputeGame_Test:test_defendRoot_invalidMove_reverts() (gas: 13294)
FaultDisputeGame_Test:test_extraData_succeeds() (gas: 17448) FaultDisputeGame_Test:test_extraData_succeeds() (gas: 17426)
FaultDisputeGame_Test:test_gameData_succeeds() (gas: 17873) FaultDisputeGame_Test:test_gameData_succeeds() (gas: 17917)
FaultDisputeGame_Test:test_gameStart_succeeds() (gas: 10337) FaultDisputeGame_Test:test_gameStart_succeeds() (gas: 10315)
FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8216) FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8282)
FaultDisputeGame_Test:test_initialRootClaimData_succeeds() (gas: 17691) FaultDisputeGame_Test:test_initialRootClaimData_succeeds() (gas: 17691)
FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 26410) FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 26387)
FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 103231) FaultDisputeGame_Test:test_move_duplicateClaim_reverts() (gas: 103230)
FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 407967) FaultDisputeGame_Test:test_move_gameDepthExceeded_reverts() (gas: 408100)
FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 10923) FaultDisputeGame_Test:test_move_gameNotInProgress_reverts() (gas: 10923)
FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24632) FaultDisputeGame_Test:test_move_nonExistentParent_reverts() (gas: 24655)
FaultDisputeGame_Test:test_resolve_challengeContested() (gas: 221068) FaultDisputeGame_Test:test_resolve_challengeContested_succeeds() (gas: 221201)
FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9657) FaultDisputeGame_Test:test_resolve_notInProgress_reverts() (gas: 9679)
FaultDisputeGame_Test:test_resolve_rootContested() (gas: 106120) FaultDisputeGame_Test:test_resolve_rootContested_succeeds() (gas: 106068)
FaultDisputeGame_Test:test_resolve_rootUncontested() (gas: 23624) FaultDisputeGame_Test:test_resolve_rootUncontested_succeeds() (gas: 23692)
FaultDisputeGame_Test:test_resolve_teamDeathmatch() (gas: 391731) FaultDisputeGame_Test:test_resolve_teamDeathmatch_succeeds() (gas: 391875)
FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8203) FaultDisputeGame_Test:test_rootClaim_succeeds() (gas: 8181)
FaultDisputeGame_Test:test_simpleAttack_succeeds() (gas: 107322) FaultDisputeGame_Test:test_simpleAttack_succeeds() (gas: 107388)
FeeVault_Test:test_constructor_succeeds() (gas: 18185) FeeVault_Test:test_constructor_succeeds() (gas: 18185)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 352135) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 352135)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2950342) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2950342)
......
...@@ -72,12 +72,12 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -72,12 +72,12 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
/// @inheritdoc IFaultDisputeGame /// @inheritdoc IFaultDisputeGame
function attack(uint256 _parentIndex, Claim _pivot) external payable { function attack(uint256 _parentIndex, Claim _pivot) external payable {
_move(_parentIndex, _pivot, true); move(_parentIndex, _pivot, true);
} }
/// @inheritdoc IFaultDisputeGame /// @inheritdoc IFaultDisputeGame
function defend(uint256 _parentIndex, Claim _pivot) external payable { function defend(uint256 _parentIndex, Claim _pivot) external payable {
_move(_parentIndex, _pivot, false); move(_parentIndex, _pivot, false);
} }
/// @inheritdoc IFaultDisputeGame /// @inheritdoc IFaultDisputeGame
...@@ -162,11 +162,11 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -162,11 +162,11 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
/// @param _challengeIndex The index of the claim being moved against. /// @param _challengeIndex The index of the claim being moved against.
/// @param _pivot The claim at the next logical position in the game. /// @param _pivot The claim at the next logical position in the game.
/// @param _isAttack Whether or not the move is an attack or defense. /// @param _isAttack Whether or not the move is an attack or defense.
function _move( function move(
uint256 _challengeIndex, uint256 _challengeIndex,
Claim _pivot, Claim _pivot,
bool _isAttack bool _isAttack
) internal { ) public payable {
// Moves cannot be made unless the game is currently in progress. // Moves cannot be made unless the game is currently in progress.
if (status != GameStatus.IN_PROGRESS) { if (status != GameStatus.IN_PROGRESS) {
revert GameNotInProgress(); revert GameNotInProgress();
...@@ -254,6 +254,11 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -254,6 +254,11 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
l2BlockNumber_ = _getArgUint256(0x20); l2BlockNumber_ = _getArgUint256(0x20);
} }
/// @notice Returns the length of the `claimData` array.
function claimDataLen() external view returns (uint256 len_) {
len_ = claimData.length;
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// `IDisputeGame` impl // // `IDisputeGame` impl //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
......
...@@ -236,7 +236,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -236,7 +236,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
} }
/// @dev Static unit test for the correctness an uncontested root resolution. /// @dev Static unit test for the correctness an uncontested root resolution.
function test_resolve_rootUncontested() public { function test_resolve_rootUncontested_succeeds() public {
GameStatus status = gameProxy.resolve(); GameStatus status = gameProxy.resolve();
assertEq(uint8(status), uint8(GameStatus.DEFENDER_WINS)); assertEq(uint8(status), uint8(GameStatus.DEFENDER_WINS));
assertEq(uint8(gameProxy.status()), uint8(GameStatus.DEFENDER_WINS)); assertEq(uint8(gameProxy.status()), uint8(GameStatus.DEFENDER_WINS));
...@@ -260,7 +260,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -260,7 +260,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
} }
/// @dev Static unit test for the correctness of resolving a single attack game state. /// @dev Static unit test for the correctness of resolving a single attack game state.
function test_resolve_rootContested() public { function test_resolve_rootContested_succeeds() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
GameStatus status = gameProxy.resolve(); GameStatus status = gameProxy.resolve();
...@@ -269,7 +269,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -269,7 +269,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
} }
/// @dev Static unit test for the correctness of resolving a game with a contested challenge claim. /// @dev Static unit test for the correctness of resolving a game with a contested challenge claim.
function test_resolve_challengeContested() public { function test_resolve_challengeContested_succeeds() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
gameProxy.defend(1, Claim.wrap(bytes32(uint256(6)))); gameProxy.defend(1, Claim.wrap(bytes32(uint256(6))));
...@@ -279,7 +279,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init { ...@@ -279,7 +279,7 @@ contract FaultDisputeGame_Test is FaultDisputeGame_Init {
} }
/// @dev Static unit test for the correctness of resolving a game with multiplayer moves. /// @dev Static unit test for the correctness of resolving a game with multiplayer moves.
function test_resolve_teamDeathmatch() public { function test_resolve_teamDeathmatch_succeeds() public {
gameProxy.attack(0, Claim.wrap(bytes32(uint256(5)))); gameProxy.attack(0, Claim.wrap(bytes32(uint256(5))));
gameProxy.attack(0, Claim.wrap(bytes32(uint256(4)))); gameProxy.attack(0, Claim.wrap(bytes32(uint256(4))));
gameProxy.defend(1, Claim.wrap(bytes32(uint256(6)))); gameProxy.defend(1, Claim.wrap(bytes32(uint256(6))));
...@@ -391,7 +391,7 @@ contract GamePlayer { ...@@ -391,7 +391,7 @@ contract GamePlayer {
// Now, search for the index of the claim that commits to the prestate's trace // Now, search for the index of the claim that commits to the prestate's trace
// index. // index.
uint256 len = claimDataLen(); uint256 len = gameProxy.claimDataLen();
for (uint256 i = 0; i < len; i++) { for (uint256 i = 0; i < len; i++) {
(, , , Position pos, ) = gameProxy.claimData(i); (, , , Position pos, ) = gameProxy.claimData(i);
if (Position.unwrap(pos) == Position.unwrap(statePos)) { if (Position.unwrap(pos) == Position.unwrap(statePos)) {
...@@ -424,7 +424,7 @@ contract GamePlayer { ...@@ -424,7 +424,7 @@ contract GamePlayer {
// Attack the parent claim. // Attack the parent claim.
gameProxy.attack(_parentIndex, ourClaim); gameProxy.attack(_parentIndex, ourClaim);
// Call out to our counter party to respond. // Call out to our counter party to respond.
counterParty.play(claimDataLen() - 1); counterParty.play(gameProxy.claimDataLen() - 1);
// If we have a second move position, attack the grandparent. // If we have a second move position, attack the grandparent.
if (Position.unwrap(movePos2) != 0) { if (Position.unwrap(movePos2) != 0) {
...@@ -432,22 +432,17 @@ contract GamePlayer { ...@@ -432,22 +432,17 @@ contract GamePlayer {
Claim ourGrandparentClaim = claimAt(grandparentPos.move(true)); Claim ourGrandparentClaim = claimAt(grandparentPos.move(true));
gameProxy.attack(grandparentIndex, ourGrandparentClaim); gameProxy.attack(grandparentIndex, ourGrandparentClaim);
counterParty.play(claimDataLen() - 1); counterParty.play(gameProxy.claimDataLen() - 1);
} }
} else { } else {
// Defend the parent claim. // Defend the parent claim.
gameProxy.defend(_parentIndex, ourClaim); gameProxy.defend(_parentIndex, ourClaim);
// Call out to our counter party to respond. // Call out to our counter party to respond.
counterParty.play(claimDataLen() - 1); counterParty.play(gameProxy.claimDataLen() - 1);
} }
} }
} }
/// @notice Returns the length of the claim data array.
function claimDataLen() internal view returns (uint256 len_) {
return uint256(vm.load(address(gameProxy), bytes32(uint256(1))));
}
/// @notice Returns the state at the trace index within the player's trace. /// @notice Returns the state at the trace index within the player's trace.
function traceAt(Position _position) public view returns (uint256 state_) { function traceAt(Position _position) public view returns (uint256 state_) {
return traceAt(_position.traceIndex(maxDepth)); return traceAt(_position.traceIndex(maxDepth));
......
import assert from 'assert'
import { task, types } from 'hardhat/config'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import { Contract, providers, Wallet, Signer, BigNumber } from 'ethers'
import { predeploys } from '../src'
// expectedSemver is the semver version of the contracts
// deployed at bedrock deployment
const expectedSemver = '1.0.0'
const implSlot =
'0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc'
const adminSlot =
'0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103'
const prefix = '0x420000000000000000000000000000000000'
const logLoud = () => {
console.log(' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
}
const yell = (msg: string) => {
logLoud()
console.log(msg)
logLoud()
}
// checkPredeploys will ensure that all of the predeploys are set
const checkPredeploys = async (
hre: HardhatRuntimeEnvironment,
provider: providers.Provider
) => {
console.log('Checking predeploys are configured correctly')
const admin = hre.ethers.utils.hexConcat([
'0x000000000000000000000000',
predeploys.ProxyAdmin,
])
// We only check predeploys 0x420..00 through 0x420..FF on the mainnet network to
// reduce the probability of an RPC timeout. After the migration, all predeploys
// from 0x420..00 through 0x420..07FF should be checked.
const maxCheck = hre.network.name === 'mainnet' ? 256 : 2048
const codeReq = []
const slotReq = []
// First loop for requests
for (let i = 0; i < maxCheck; i++) {
const num = hre.ethers.utils.hexZeroPad('0x' + i.toString(16), 2)
const addr = hre.ethers.utils.getAddress(
hre.ethers.utils.hexConcat([prefix, num])
)
codeReq.push(provider.getCode(addr))
slotReq.push(provider.getStorageAt(addr, adminSlot))
}
// Wait for all requests to finish
// The `JsonRpcBatchProvider` will batch requests in the background.
const codeRes = await Promise.all(codeReq)
const slotRes = await Promise.all(slotReq)
// Second loop for response checks
for (let i = 0; i < maxCheck; i++) {
const num = hre.ethers.utils.hexZeroPad('0x' + i.toString(16), 2)
const addr = hre.ethers.utils.getAddress(
hre.ethers.utils.hexConcat([prefix, num])
)
if (codeRes[i] === '0x') {
throw new Error(`no code found at ${addr}`)
}
if (
addr === predeploys.GovernanceToken ||
addr === predeploys.ProxyAdmin ||
addr === predeploys.WETH9
) {
continue
}
if (slotRes[i] !== admin) {
throw new Error(`incorrect admin slot in ${addr}`)
}
if (i % (maxCheck / 4) === 0) {
console.log(`Checked through ${addr}`)
}
}
}
// assertSemver will ensure that the semver is the correct version
const assertSemver = async (
contract: Contract,
name: string,
override?: string
) => {
const version = await contract.version()
let target = expectedSemver
if (override) {
target = override
}
if (version !== target) {
throw new Error(
`${name}: version mismatch. Got ${version}, expected ${target}`
)
}
console.log(` - version: ${version}`)
}
// checkProxy will print out the proxy slots
const checkProxy = async (
_hre: HardhatRuntimeEnvironment,
name: string,
provider: providers.Provider
) => {
const address = predeploys[name]
if (!address) {
throw new Error(`unknown contract name: ${name}`)
}
const impl = await provider.getStorageAt(address, implSlot)
const admin = await provider.getStorageAt(address, adminSlot)
console.log(` - EIP-1967 implementation slot: ${impl}`)
console.log(` - EIP-1967 admin slot: ${admin}`)
}
// assertProxy will require the proxy is set
const assertProxy = async (
hre: HardhatRuntimeEnvironment,
name: string,
provider: providers.Provider
) => {
const address = predeploys[name]
if (!address) {
throw new Error(`unknown contract name: ${name}`)
}
const code = await provider.getCode(address)
const deployInfo = await hre.artifacts.readArtifact('Proxy')
if (code !== deployInfo.deployedBytecode) {
throw new Error(`${address}: code mismatch`)
}
const impl = await provider.getStorageAt(address, implSlot)
const implAddress = '0x' + impl.slice(26)
const implCode = await provider.getCode(implAddress)
if (implCode === '0x') {
throw new Error('No code at implementation')
}
}
// checks to make sure that the genesis magic value
// was set correctly
const checkGenesisMagic = async (
hre: HardhatRuntimeEnvironment,
l2Provider: providers.Provider,
args
) => {
const magic = '0x' + Buffer.from('BEDROCK').toString('hex')
let startingBlockNumber: number
// We have a connection to the L1 chain, fetch the remote value
if (args.l1RpcUrl !== '') {
const l1Provider = new hre.ethers.providers.StaticJsonRpcProvider(
args.l1RpcUrl
)
// Get the address if it was passed in via CLI
// Otherwise get the address from a hardhat deployment file
let address: string
if (args.l2OutputOracleAddress !== '') {
address = args.l2OutputOracleAddress
} else {
const Deployment__L2OutputOracle = await hre.deployments.get(
'L2OutputOracleProxy'
)
address = Deployment__L2OutputOracle.address
}
const abi = {
inputs: [],
name: 'startingBlockNumber',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
}
const L2OutputOracle = new hre.ethers.Contract(address, [abi], l1Provider)
// In the migration, the L2OutputOracle proxy is not yet initialized when we
// want to run this script. Fall back on the local config if we get an error
// fetching the starting block number.
try {
startingBlockNumber = await L2OutputOracle.startingBlockNumber()
} catch (e) {
console.log(`Error fetching startingBlockNumber:\n${e.message}`)
console.log('Falling back to local config.')
startingBlockNumber = hre.deployConfig.l2OutputOracleStartingBlockNumber
}
} else {
// We do not have a connection to the L1 chain, use the local config
// The `--network` flag must be set to the L1 network
startingBlockNumber = hre.deployConfig.l2OutputOracleStartingBlockNumber
}
// ensure that the starting block number is a number
startingBlockNumber = BigNumber.from(startingBlockNumber).toNumber()
const block = await l2Provider.getBlock(startingBlockNumber)
const extradata = block.extraData
if (extradata !== magic) {
throw new Error(
`magic value in extradata does not match: got ${extradata}, expected ${magic}`
)
}
}
const check = {
// LegacyMessagePasser
// - check version
// - is behind a proxy
LegacyMessagePasser: async (
hre: HardhatRuntimeEnvironment,
signer: Signer
) => {
const LegacyMessagePasser = await hre.ethers.getContractAt(
'LegacyMessagePasser',
predeploys.LegacyMessagePasser,
signer
)
await assertSemver(LegacyMessagePasser, 'LegacyMessagePasser', '1.0.1')
await checkProxy(hre, 'LegacyMessagePasser', signer.provider)
await assertProxy(hre, 'LegacyMessagePasser', signer.provider)
},
// DeployerWhitelist
// - check version
// - is behind a proxy
// - owner is `address(0)`
DeployerWhitelist: async (hre: HardhatRuntimeEnvironment, signer: Signer) => {
const DeployerWhitelist = await hre.ethers.getContractAt(
'DeployerWhitelist',
predeploys.DeployerWhitelist,
signer
)
await assertSemver(DeployerWhitelist, 'DeployerWhitelist', '1.0.1')
const owner = await DeployerWhitelist.owner()
assert(owner === hre.ethers.constants.AddressZero)
console.log(` - owner: ${owner}`)
await checkProxy(hre, 'DeployerWhitelist', signer.provider)
await assertProxy(hre, 'DeployerWhitelist', signer.provider)
},
// L2CrossDomainMessenger
// - check version
// - check OTHER_MESSENGER
// - check l1CrossDomainMessenger (legacy)
// - is behind a proxy
// - check owner
// - check initialized
L2CrossDomainMessenger: async (
hre: HardhatRuntimeEnvironment,
signer: Signer
) => {
const L2CrossDomainMessenger = await hre.ethers.getContractAt(
'L2CrossDomainMessenger',
predeploys.L2CrossDomainMessenger,
signer
)
await assertSemver(
L2CrossDomainMessenger,
'L2CrossDomainMessenger',
'1.4.1'
)
const xDomainMessageSenderSlot = await signer.provider.getStorageAt(
predeploys.L2CrossDomainMessenger,
204
)
const xDomainMessageSender = '0x' + xDomainMessageSenderSlot.slice(26)
assert(
xDomainMessageSender === '0x000000000000000000000000000000000000dead'
)
const otherMessenger = await L2CrossDomainMessenger.OTHER_MESSENGER()
assert(otherMessenger !== hre.ethers.constants.AddressZero)
yell(` - OTHER_MESSENGER: ${otherMessenger}`)
const l1CrossDomainMessenger =
await L2CrossDomainMessenger.l1CrossDomainMessenger()
yell(` - l1CrossDomainMessenger: ${l1CrossDomainMessenger}`)
await checkProxy(hre, 'L2CrossDomainMessenger', signer.provider)
await assertProxy(hre, 'L2CrossDomainMessenger', signer.provider)
const MESSAGE_VERSION = await L2CrossDomainMessenger.MESSAGE_VERSION()
console.log(` - MESSAGE_VERSION: ${MESSAGE_VERSION}`)
const MIN_GAS_CALLDATA_OVERHEAD =
await L2CrossDomainMessenger.MIN_GAS_CALLDATA_OVERHEAD()
console.log(` - MIN_GAS_CALLDATA_OVERHEAD: ${MIN_GAS_CALLDATA_OVERHEAD}`)
const RELAY_CONSTANT_OVERHEAD =
await L2CrossDomainMessenger.RELAY_CONSTANT_OVERHEAD()
console.log(` - RELAY_CONSTANT_OVERHEAD: ${RELAY_CONSTANT_OVERHEAD}`)
const MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR =
await L2CrossDomainMessenger.MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR()
console.log(
` - MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR: ${MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR}`
)
const MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR =
await L2CrossDomainMessenger.MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR()
console.log(
` - MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR: ${MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR}`
)
const RELAY_CALL_OVERHEAD =
await L2CrossDomainMessenger.RELAY_CALL_OVERHEAD()
console.log(` - RELAY_CALL_OVERHEAD: ${RELAY_CALL_OVERHEAD}`)
const RELAY_RESERVED_GAS = await L2CrossDomainMessenger.RELAY_RESERVED_GAS()
console.log(` - RELAY_RESERVED_GAS: ${RELAY_RESERVED_GAS}`)
const RELAY_GAS_CHECK_BUFFER =
await L2CrossDomainMessenger.RELAY_GAS_CHECK_BUFFER()
console.log(` - RELAY_GAS_CHECK_BUFFER: ${RELAY_GAS_CHECK_BUFFER}`)
const slot = await signer.provider.getStorageAt(
predeploys.L2CrossDomainMessenger,
0
)
const spacer = '0x' + slot.slice(26)
console.log(` - legacy spacer: ${spacer}`)
const initialized = '0x' + slot.slice(24, 26)
assert(initialized === '0x01')
console.log(` - initialized: ${initialized}`)
},
// GasPriceOracle
// - check version
// - check decimals
GasPriceOracle: async (hre: HardhatRuntimeEnvironment, signer: Signer) => {
const GasPriceOracle = await hre.ethers.getContractAt(
'GasPriceOracle',
predeploys.GasPriceOracle,
signer
)
await assertSemver(GasPriceOracle, 'GasPriceOracle', '1.0.1')
const decimals = await GasPriceOracle.decimals()
assert(decimals.eq(6))
console.log(` - decimals: ${decimals.toNumber()}`)
await checkProxy(hre, 'GasPriceOracle', signer.provider)
await assertProxy(hre, 'GasPriceOracle', signer.provider)
},
// L2StandardBridge
// - check version
L2StandardBridge: async (hre: HardhatRuntimeEnvironment, signer: Signer) => {
const L2StandardBridge = await hre.ethers.getContractAt(
'L2StandardBridge',
predeploys.L2StandardBridge,
signer
)
await assertSemver(L2StandardBridge, 'L2StandardBridge', '1.1.1')
const OTHER_BRIDGE = await L2StandardBridge.OTHER_BRIDGE()
assert(OTHER_BRIDGE !== hre.ethers.constants.AddressZero)
yell(` - OTHER_BRIDGE: ${OTHER_BRIDGE}`)
const MESSENGER = await L2StandardBridge.MESSENGER()
assert(MESSENGER === predeploys.L2CrossDomainMessenger)
await checkProxy(hre, 'L2StandardBridge', signer.provider)
await assertProxy(hre, 'L2StandardBridge', signer.provider)
},
// SequencerFeeVault
// - check version
// - check RECIPIENT
// - check l1FeeWallet (legacy)
SequencerFeeVault: async (hre: HardhatRuntimeEnvironment, signer: Signer) => {
const SequencerFeeVault = await hre.ethers.getContractAt(
'SequencerFeeVault',
predeploys.SequencerFeeVault,
signer
)
await assertSemver(SequencerFeeVault, 'SequencerFeeVault', '1.2.1')
const RECIPIENT = await SequencerFeeVault.RECIPIENT()
assert(RECIPIENT !== hre.ethers.constants.AddressZero)
yell(` - RECIPIENT: ${RECIPIENT}`)
const l1FeeWallet = await SequencerFeeVault.l1FeeWallet()
assert(l1FeeWallet !== hre.ethers.constants.AddressZero)
console.log(` - l1FeeWallet: ${l1FeeWallet}`)
const MIN_WITHDRAWAL_AMOUNT =
await SequencerFeeVault.MIN_WITHDRAWAL_AMOUNT()
console.log(` - MIN_WITHDRAWAL_AMOUNT: ${MIN_WITHDRAWAL_AMOUNT}`)
const WITHDRAWAL_NETWORK = await SequencerFeeVault.WITHDRAWAL_NETWORK()
assert(WITHDRAWAL_NETWORK < 2)
console.log(` - WITHDRAWAL_NETWORK: ${WITHDRAWAL_NETWORK}`)
await checkProxy(hre, 'SequencerFeeVault', signer.provider)
await assertProxy(hre, 'SequencerFeeVault', signer.provider)
},
// OptimismMintableERC20Factory
// - check version
OptimismMintableERC20Factory: async (
hre: HardhatRuntimeEnvironment,
signer: Signer
) => {
const OptimismMintableERC20Factory = await hre.ethers.getContractAt(
'OptimismMintableERC20Factory',
predeploys.OptimismMintableERC20Factory,
signer
)
await assertSemver(
OptimismMintableERC20Factory,
'OptimismMintableERC20Factory',
'1.1.1'
)
const BRIDGE = await OptimismMintableERC20Factory.BRIDGE()
assert(BRIDGE !== hre.ethers.constants.AddressZero)
await checkProxy(hre, 'OptimismMintableERC20Factory', signer.provider)
await assertProxy(hre, 'OptimismMintableERC20Factory', signer.provider)
},
// L1BlockNumber
// - check version
L1BlockNumber: async (hre: HardhatRuntimeEnvironment, signer: Signer) => {
const L1BlockNumber = await hre.ethers.getContractAt(
'L1BlockNumber',
predeploys.L1BlockNumber,
signer
)
await assertSemver(L1BlockNumber, 'L1BlockNumber', '1.0.1')
await checkProxy(hre, 'L1BlockNumber', signer.provider)
await assertProxy(hre, 'L1BlockNumber', signer.provider)
},
// L1Block
// - check version
L1Block: async (hre: HardhatRuntimeEnvironment, signer: Signer) => {
const L1Block = await hre.ethers.getContractAt(
'L1Block',
predeploys.L1Block,
signer
)
await assertSemver(L1Block, 'L1Block', '1.0.1')
await checkProxy(hre, 'L1Block', signer.provider)
await assertProxy(hre, 'L1Block', signer.provider)
},
// WETH9
// - check name
// - check symbol
// - check decimals
WETH9: async (hre: HardhatRuntimeEnvironment, signer: Signer) => {
const WETH9 = await hre.ethers.getContractAt(
'WETH9',
predeploys.WETH9,
signer
)
const name = await WETH9.name()
assert(name === 'Wrapped Ether')
console.log(` - name: ${name}`)
const symbol = await WETH9.symbol()
assert(symbol === 'WETH')
console.log(` - symbol: ${symbol}`)
const decimals = await WETH9.decimals()
assert(decimals === 18)
console.log(` - decimals: ${decimals}`)
},
// GovernanceToken
// - not behind a proxy
// - check name
// - check symbol
// - check owner
GovernanceToken: async (hre: HardhatRuntimeEnvironment, signer: Signer) => {
const GovernanceToken = await hre.ethers.getContractAt(
'GovernanceToken',
predeploys.GovernanceToken,
signer
)
const name = await GovernanceToken.name()
assert(name === 'Optimism')
console.log(` - name: ${name}`)
const symbol = await GovernanceToken.symbol()
assert(symbol === 'OP')
console.log(` - symbol: ${symbol}`)
const owner = await GovernanceToken.owner()
yell(` - owner: ${owner}`)
const totalSupply = await GovernanceToken.totalSupply()
console.log(` - totalSupply: ${totalSupply}`)
await checkProxy(hre, 'GovernanceToken', signer.provider)
// No proxy at this address, don't call assertProxy
},
// L2ERC721Bridge
// - check version
L2ERC721Bridge: async (hre: HardhatRuntimeEnvironment, signer: Signer) => {
const L2ERC721Bridge = await hre.ethers.getContractAt(
'L2ERC721Bridge',
predeploys.L2ERC721Bridge,
signer
)
await assertSemver(L2ERC721Bridge, 'L2ERC721Bridge', '1.1.1')
const MESSENGER = await L2ERC721Bridge.MESSENGER()
assert(MESSENGER !== hre.ethers.constants.AddressZero)
console.log(` - MESSENGER: ${MESSENGER}`)
const OTHER_BRIDGE = await L2ERC721Bridge.OTHER_BRIDGE()
assert(OTHER_BRIDGE !== hre.ethers.constants.AddressZero)
yell(` - OTHER_BRIDGE: ${OTHER_BRIDGE}`)
await checkProxy(hre, 'L2ERC721Bridge', signer.provider)
await assertProxy(hre, 'L2ERC721Bridge', signer.provider)
},
// OptimismMintableERC721Factory
// - check version
OptimismMintableERC721Factory: async (
hre: HardhatRuntimeEnvironment,
signer: Signer
) => {
const OptimismMintableERC721Factory = await hre.ethers.getContractAt(
'OptimismMintableERC721Factory',
predeploys.OptimismMintableERC721Factory,
signer
)
await assertSemver(
OptimismMintableERC721Factory,
'OptimismMintableERC721Factory',
'1.2.1'
)
const BRIDGE = await OptimismMintableERC721Factory.BRIDGE()
assert(BRIDGE !== hre.ethers.constants.AddressZero)
console.log(` - BRIDGE: ${BRIDGE}`)
const REMOTE_CHAIN_ID =
await OptimismMintableERC721Factory.REMOTE_CHAIN_ID()
assert(REMOTE_CHAIN_ID !== 0)
console.log(` - REMOTE_CHAIN_ID: ${REMOTE_CHAIN_ID}`)
await checkProxy(hre, 'OptimismMintableERC721Factory', signer.provider)
await assertProxy(hre, 'OptimismMintableERC721Factory', signer.provider)
},
// ProxyAdmin
// - check owner
ProxyAdmin: async (hre: HardhatRuntimeEnvironment, signer: Signer) => {
const ProxyAdmin = await hre.ethers.getContractAt(
'ProxyAdmin',
predeploys.ProxyAdmin,
signer
)
const owner = await ProxyAdmin.owner()
assert(owner !== hre.ethers.constants.AddressZero)
yell(` - owner: ${owner}`)
const addressManager = await ProxyAdmin.addressManager()
console.log(` - addressManager: ${addressManager}`)
await checkProxy(hre, 'ProxyAdmin', signer.provider)
await assertProxy(hre, 'ProxyAdmin', signer.provider)
},
// BaseFeeVault
// - check version
// - check MIN_WITHDRAWAL_AMOUNT
// - check RECIPIENT
BaseFeeVault: async (hre: HardhatRuntimeEnvironment, signer: Signer) => {
const BaseFeeVault = await hre.ethers.getContractAt(
'BaseFeeVault',
predeploys.BaseFeeVault,
signer
)
await assertSemver(BaseFeeVault, 'BaseFeeVault', '1.2.1')
const MIN_WITHDRAWAL_AMOUNT = await BaseFeeVault.MIN_WITHDRAWAL_AMOUNT()
console.log(` - MIN_WITHDRAWAL_AMOUNT: ${MIN_WITHDRAWAL_AMOUNT}`)
const RECIPIENT = await BaseFeeVault.RECIPIENT()
assert(RECIPIENT !== hre.ethers.constants.AddressZero)
yell(` - RECIPIENT: ${RECIPIENT}`)
const WITHDRAWAL_NETWORK = await BaseFeeVault.WITHDRAWAL_NETWORK()
assert(WITHDRAWAL_NETWORK < 2)
console.log(` - WITHDRAWAL_NETWORK: ${WITHDRAWAL_NETWORK}`)
await checkProxy(hre, 'BaseFeeVault', signer.provider)
await assertProxy(hre, 'BaseFeeVault', signer.provider)
},
// L1FeeVault
// - check version
// - check MIN_WITHDRAWAL_AMOUNT
// - check RECIPIENT
L1FeeVault: async (hre: HardhatRuntimeEnvironment, signer: Signer) => {
const L1FeeVault = await hre.ethers.getContractAt(
'L1FeeVault',
predeploys.L1FeeVault,
signer
)
await assertSemver(L1FeeVault, 'L1FeeVault', '1.2.1')
const MIN_WITHDRAWAL_AMOUNT = await L1FeeVault.MIN_WITHDRAWAL_AMOUNT()
console.log(` - MIN_WITHDRAWAL_AMOUNT: ${MIN_WITHDRAWAL_AMOUNT}`)
const RECIPIENT = await L1FeeVault.RECIPIENT()
assert(RECIPIENT !== hre.ethers.constants.AddressZero)
yell(` - RECIPIENT: ${RECIPIENT}`)
const WITHDRAWAL_NETWORK = await L1FeeVault.WITHDRAWAL_NETWORK()
assert(WITHDRAWAL_NETWORK < 2)
console.log(` - WITHDRAWAL_NETWORK: ${WITHDRAWAL_NETWORK}`)
await checkProxy(hre, 'L1FeeVault', signer.provider)
await assertProxy(hre, 'L1FeeVault', signer.provider)
},
// L2ToL1MessagePasser
// - check version
L2ToL1MessagePasser: async (
hre: HardhatRuntimeEnvironment,
signer: Signer
) => {
const L2ToL1MessagePasser = await hre.ethers.getContractAt(
'L2ToL1MessagePasser',
predeploys.L2ToL1MessagePasser,
signer
)
await assertSemver(L2ToL1MessagePasser, 'L2ToL1MessagePasser', '1.0.1')
const MESSAGE_VERSION = await L2ToL1MessagePasser.MESSAGE_VERSION()
console.log(` - MESSAGE_VERSION: ${MESSAGE_VERSION}`)
const messageNonce = await L2ToL1MessagePasser.messageNonce()
console.log(` - messageNonce: ${messageNonce}`)
await checkProxy(hre, 'L2ToL1MessagePasser', signer.provider)
await assertProxy(hre, 'L2ToL1MessagePasser', signer.provider)
},
}
task('check-l2', 'Checks a freshly migrated L2 system for correct migration')
.addOptionalParam('l1RpcUrl', 'L1 RPC URL of node', '', types.string)
.addOptionalParam('l2RpcUrl', 'L2 RPC URL of node', '', types.string)
.addOptionalParam('chainId', 'Expected chain id', 0, types.int)
.addOptionalParam(
'l2OutputOracleAddress',
'Address of the L2OutputOracle oracle',
'',
types.string
)
.addOptionalParam(
'skipPredeployCheck',
'Skip long check',
false,
types.boolean
)
.setAction(async (args, hre: HardhatRuntimeEnvironment) => {
yell('Manually check values wrapped in !!!!')
console.log()
let signer: Signer = hre.ethers.provider.getSigner()
if (args.l2RpcUrl !== '') {
console.log('Using CLI URL for provider instead of hardhat network')
const provider = new hre.ethers.providers.JsonRpcBatchProvider(
args.l2RpcUrl
)
signer = Wallet.createRandom().connect(provider)
}
if (args.chainId !== 0) {
const chainId = await signer.getChainId()
if (chainId !== args.chainId) {
throw new Error(
`Unexpected Chain ID. Got ${chainId}, expected ${args.chainId}`
)
}
console.log(`Verified Chain ID: ${chainId}`)
} else {
console.log(`Skipping Chain ID validation...`)
}
// Ensure that all the predeploys exist, including the not
// currently configured ones
if (!args.skipPredeployCheck) {
await checkPredeploys(hre, signer.provider)
}
await checkGenesisMagic(hre, signer.provider, args)
console.log()
// Check the currently configured predeploys
for (const [name, fn] of Object.entries(check)) {
const address = predeploys[name]
console.log(`${name}: ${address}`)
await fn(hre, signer)
}
})
import './solidity' import './solidity'
import './check-l2'
import './generate-deploy-config' import './generate-deploy-config'
...@@ -17,8 +17,6 @@ ...@@ -17,8 +17,6 @@
- [Configuration](#configuration) - [Configuration](#configuration)
- [Security Considerations](#security-considerations) - [Security Considerations](#security-considerations)
- [L1 Reorgs](#l1-reorgs) - [L1 Reorgs](#l1-reorgs)
- [Summary of Definitions](#summary-of-definitions)
- [Constants](#constants)
<!-- END doctoc generated TOC please keep comment here to allow auto update --> <!-- END doctoc generated TOC please keep comment here to allow auto update -->
...@@ -225,12 +223,3 @@ If the L1 has a reorg after an output has been generated and submitted, the L2 s ...@@ -225,12 +223,3 @@ If the L1 has a reorg after an output has been generated and submitted, the L2 s
leading to a faulty proposal. This is mitigated against by allowing the proposer to submit an leading to a faulty proposal. This is mitigated against by allowing the proposer to submit an
L1 block number and hash to the Output Oracle when appending a new output; in the event of a reorg, the block hash L1 block number and hash to the Output Oracle when appending a new output; in the event of a reorg, the block hash
will not match that of the block with that number and the call will revert. will not match that of the block with that number and the call will revert.
## Summary of Definitions
### Constants
| Name | Value | Unit |
| --------------------- | ------- | ------- |
| `SUBMISSION_INTERVAL` | `120` | blocks |
| `L2_BLOCK_TIME` | `2` | seconds |
...@@ -48,8 +48,6 @@ finalization. ...@@ -48,8 +48,6 @@ finalization.
- [Security Considerations](#security-considerations) - [Security Considerations](#security-considerations)
- [Key Properties of Withdrawal Verification](#key-properties-of-withdrawal-verification) - [Key Properties of Withdrawal Verification](#key-properties-of-withdrawal-verification)
- [Handling Successfully Verified Messages That Fail When Relayed](#handling-successfully-verified-messages-that-fail-when-relayed) - [Handling Successfully Verified Messages That Fail When Relayed](#handling-successfully-verified-messages-that-fail-when-relayed)
- [Summary of Definitions](#summary-of-definitions)
- [Constants](#constants)
<!-- END doctoc generated TOC please keep comment here to allow auto update --> <!-- END doctoc generated TOC please keep comment here to allow auto update -->
...@@ -216,15 +214,5 @@ whether or not it was 'supposed' to fail, and whether or not it should be 'repla ...@@ -216,15 +214,5 @@ whether or not it was 'supposed' to fail, and whether or not it should be 'repla
minimize complexity, we have not provided any replay functionality, this may be implemented in external utility minimize complexity, we have not provided any replay functionality, this may be implemented in external utility
contracts if desired. contracts if desired.
## Summary of Definitions
### Constants
| Name | Value | Unit |
| --------------------- | --------- | ------- |
| `FINALIZATION_PERIOD` | `604_800` | seconds |
This `FINALIZATION_PERIOD` value is equivalent to 7 days.
[`WithdrawalTransaction` type]: https://github.com/ethereum-optimism/optimism/blob/6c6d142d7bb95faa11066aab5d8aed7187abfe38/packages/contracts-bedrock/contracts/libraries/Types.sol#L76-L83 [`WithdrawalTransaction` type]: https://github.com/ethereum-optimism/optimism/blob/6c6d142d7bb95faa11066aab5d8aed7187abfe38/packages/contracts-bedrock/contracts/libraries/Types.sol#L76-L83
[`OutputRootProof` type]: https://github.com/ethereum-optimism/optimism/blob/6c6d142d7bb95faa11066aab5d8aed7187abfe38/packages/contracts-bedrock/contracts/libraries/Types.sol#L33-L38 [`OutputRootProof` type]: https://github.com/ethereum-optimism/optimism/blob/6c6d142d7bb95faa11066aab5d8aed7187abfe38/packages/contracts-bedrock/contracts/libraries/Types.sol#L33-L38
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