From 9eff237050ef574add6da8b387f04d3f3e50fab9 Mon Sep 17 00:00:00 2001 From: curryxbo Date: Thu, 6 Jul 2023 22:51:00 +0800 Subject: [PATCH 1/4] fix --- indexer/docker-compose.yml | 16 +- l2geth/tests/testdata | 1 + op-bindings/bindings/addressmanager.go | 5 +- op-bindings/bindings/basefeevault.go | 5 +- op-bindings/bindings/deployerwhitelist.go | 5 +- op-bindings/bindings/erc20.go | 7 +- op-bindings/bindings/gaspriceoracle.go | 5 +- op-bindings/bindings/l1block.go | 5 +- op-bindings/bindings/l1blocknumber.go | 5 +- .../bindings/l1crossdomainmessenger.go | 5 +- op-bindings/bindings/l1erc721bridge.go | 5 +- op-bindings/bindings/l1feevault.go | 5 +- op-bindings/bindings/l1standardbridge.go | 5 +- .../bindings/l2crossdomainmessenger.go | 5 +- op-bindings/bindings/l2erc721bridge.go | 5 +- op-bindings/bindings/l2outputoracle.go | 5 +- op-bindings/bindings/l2standardbridge.go | 5 +- op-bindings/bindings/l2tol1messagepasser.go | 5 +- op-bindings/bindings/legacyerc20eth.go | 5 +- op-bindings/bindings/legacymessagepasser.go | 5 +- op-bindings/bindings/optimismmintableerc20.go | 5 +- .../bindings/optimismmintableerc20factory.go | 5 +- .../bindings/optimismmintableerc721factory.go | 5 +- op-bindings/bindings/optimismportal.go | 68 +- op-bindings/bindings/proxy.go | 5 +- op-bindings/bindings/proxyadmin.go | 5 +- op-bindings/bindings/sequencerfeevault.go | 5 +- op-bindings/bindings/systemconfig.go | 5 +- op-bindings/bindings/weth9.go | 7 +- op-chain-ops/deployer/deployer.go | 13 + .../contracts/L1/OptimismPortal.sol | 18 +- .../L1/deployment/AddressDictator.sol | 95 +++ .../L1/deployment/ChugSplashDictator.sol | 73 ++ .../L1/messaging/IL1CrossDomainMessenger.sol | 63 ++ .../contracts/L1/messaging/IL1ERC20Bridge.sol | 104 +++ .../L1/messaging/IL1StandardBridge.sol | 75 ++ .../L1/messaging/L1CrossDomainMessenger.sol | 377 +++++++++ .../L1/messaging/L1StandardBridge.sol | 264 ++++++ .../L1/rollup/CanonicalTransactionChain.sol | 537 +++++++++++++ .../L1/rollup/ChainStorageContainer.sol | 133 +++ .../L1/rollup/ICanonicalTransactionChain.sol | 163 ++++ .../L1/rollup/IChainStorageContainer.sol | 67 ++ .../L1/rollup/IStateCommitmentChain.sol | 82 ++ .../L1/rollup/StateCommitmentChain.sol | 309 +++++++ .../contracts/L1/verification/BondManager.sol | 30 + .../L1/verification/IBondManager.sol | 19 + .../L2/messaging/IL2CrossDomainMessenger.sol | 28 + .../contracts/L2/messaging/IL2ERC20Bridge.sol | 108 +++ .../L2/messaging/L2CrossDomainMessenger.sol | 157 ++++ .../L2/messaging/L2StandardBridge.sol | 188 +++++ .../L2/messaging/L2StandardTokenFactory.sol | 38 + .../L2/predeploys/OVM_DeployerWhitelist.sol | 88 ++ packages/contracts/L2/predeploys/OVM_ETH.sol | 60 ++ .../L2/predeploys/OVM_GasPriceOracle.sol | 162 ++++ .../L2/predeploys/OVM_L2ToL1MessagePasser.sol | 35 + .../L2/predeploys/OVM_SequencerFeeVault.sol | 70 ++ packages/contracts/L2/predeploys/WETH9.sol | 756 ++++++++++++++++++ .../L2/predeploys/iOVM_L1BlockNumber.sol | 16 + .../predeploys/iOVM_L2ToL1MessagePasser.sol | 23 + .../chugsplash/L1ChugSplashProxy.sol | 285 +++++++ .../interfaces/iL1ChugSplashDeployer.sol | 9 + .../libraries/bridge/CrossDomainEnabled.sol | 83 ++ .../bridge/ICrossDomainMessenger.sol | 43 + .../libraries/bridge/Lib_CrossDomainUtils.sol | 31 + .../libraries/codec/Lib_OVMCodec.sol | 143 ++++ .../libraries/constants/Lib_DefaultValues.sol | 12 + .../constants/Lib_PredeployAddresses.sol | 21 + .../libraries/resolver/Lib_AddressManager.sol | 61 ++ .../resolver/Lib_AddressResolver.sol | 40 + .../resolver/Lib_ResolvedDelegateProxy.sol | 63 ++ .../contracts/libraries/rlp/Lib_RLPReader.sol | 388 +++++++++ .../contracts/libraries/rlp/Lib_RLPWriter.sol | 208 +++++ .../libraries/trie/Lib_MerkleTrie.sol | 304 +++++++ .../libraries/trie/Lib_SecureMerkleTrie.sol | 66 ++ .../contracts/libraries/utils/Lib_Buffer.sol | 188 +++++ .../libraries/utils/Lib_Bytes32Utils.sol | 47 ++ .../libraries/utils/Lib_BytesUtils.sol | 127 +++ .../libraries/utils/Lib_MerkleTree.sol | 175 ++++ packages/contracts/src/contract-artifacts.ts | 363 +++++++++ .../src/contract-deployed-artifacts.ts | 62 ++ .../standards/AddressAliasHelper.sol | 43 + .../contracts/standards/IL2StandardERC20.sol | 16 + .../contracts/standards/L2StandardERC20.sol | 54 ++ 83 files changed, 7117 insertions(+), 85 deletions(-) create mode 160000 l2geth/tests/testdata create mode 100644 packages/contracts/L1/deployment/AddressDictator.sol create mode 100644 packages/contracts/L1/deployment/ChugSplashDictator.sol create mode 100644 packages/contracts/L1/messaging/IL1CrossDomainMessenger.sol create mode 100644 packages/contracts/L1/messaging/IL1ERC20Bridge.sol create mode 100644 packages/contracts/L1/messaging/IL1StandardBridge.sol create mode 100644 packages/contracts/L1/messaging/L1CrossDomainMessenger.sol create mode 100644 packages/contracts/L1/messaging/L1StandardBridge.sol create mode 100644 packages/contracts/L1/rollup/CanonicalTransactionChain.sol create mode 100644 packages/contracts/L1/rollup/ChainStorageContainer.sol create mode 100644 packages/contracts/L1/rollup/ICanonicalTransactionChain.sol create mode 100644 packages/contracts/L1/rollup/IChainStorageContainer.sol create mode 100644 packages/contracts/L1/rollup/IStateCommitmentChain.sol create mode 100644 packages/contracts/L1/rollup/StateCommitmentChain.sol create mode 100644 packages/contracts/L1/verification/BondManager.sol create mode 100644 packages/contracts/L1/verification/IBondManager.sol create mode 100644 packages/contracts/L2/messaging/IL2CrossDomainMessenger.sol create mode 100644 packages/contracts/L2/messaging/IL2ERC20Bridge.sol create mode 100644 packages/contracts/L2/messaging/L2CrossDomainMessenger.sol create mode 100644 packages/contracts/L2/messaging/L2StandardBridge.sol create mode 100644 packages/contracts/L2/messaging/L2StandardTokenFactory.sol create mode 100644 packages/contracts/L2/predeploys/OVM_DeployerWhitelist.sol create mode 100644 packages/contracts/L2/predeploys/OVM_ETH.sol create mode 100644 packages/contracts/L2/predeploys/OVM_GasPriceOracle.sol create mode 100644 packages/contracts/L2/predeploys/OVM_L2ToL1MessagePasser.sol create mode 100644 packages/contracts/L2/predeploys/OVM_SequencerFeeVault.sol create mode 100644 packages/contracts/L2/predeploys/WETH9.sol create mode 100644 packages/contracts/L2/predeploys/iOVM_L1BlockNumber.sol create mode 100644 packages/contracts/L2/predeploys/iOVM_L2ToL1MessagePasser.sol create mode 100644 packages/contracts/chugsplash/L1ChugSplashProxy.sol create mode 100644 packages/contracts/chugsplash/interfaces/iL1ChugSplashDeployer.sol create mode 100644 packages/contracts/libraries/bridge/CrossDomainEnabled.sol create mode 100644 packages/contracts/libraries/bridge/ICrossDomainMessenger.sol create mode 100644 packages/contracts/libraries/bridge/Lib_CrossDomainUtils.sol create mode 100644 packages/contracts/libraries/codec/Lib_OVMCodec.sol create mode 100644 packages/contracts/libraries/constants/Lib_DefaultValues.sol create mode 100644 packages/contracts/libraries/constants/Lib_PredeployAddresses.sol create mode 100644 packages/contracts/libraries/resolver/Lib_AddressManager.sol create mode 100644 packages/contracts/libraries/resolver/Lib_AddressResolver.sol create mode 100644 packages/contracts/libraries/resolver/Lib_ResolvedDelegateProxy.sol create mode 100644 packages/contracts/libraries/rlp/Lib_RLPReader.sol create mode 100644 packages/contracts/libraries/rlp/Lib_RLPWriter.sol create mode 100644 packages/contracts/libraries/trie/Lib_MerkleTrie.sol create mode 100644 packages/contracts/libraries/trie/Lib_SecureMerkleTrie.sol create mode 100644 packages/contracts/libraries/utils/Lib_Buffer.sol create mode 100644 packages/contracts/libraries/utils/Lib_Bytes32Utils.sol create mode 100644 packages/contracts/libraries/utils/Lib_BytesUtils.sol create mode 100644 packages/contracts/libraries/utils/Lib_MerkleTree.sol create mode 100644 packages/contracts/src/contract-artifacts.ts create mode 100644 packages/contracts/src/contract-deployed-artifacts.ts create mode 100644 packages/contracts/standards/AddressAliasHelper.sol create mode 100644 packages/contracts/standards/IL2StandardERC20.sol create mode 100644 packages/contracts/standards/L2StandardERC20.sol diff --git a/indexer/docker-compose.yml b/indexer/docker-compose.yml index 639168d8e0f87..783d50d138107 100644 --- a/indexer/docker-compose.yml +++ b/indexer/docker-compose.yml @@ -32,21 +32,21 @@ services: - INDEXER_DB_PASSWORD=${INDEXER_DB_PASSWORD:-db_password} - INDEXER_DB_NAME=${INDEXER_DB_NAME:-db_name} - INDEXER_DB_HOST=${INDEXER_DB_HOST:-postgres} - - INDEXER_CHAIN_ID=${INDEXER_CHAIN_ID:-5} - - INDEXER_L1_ETH_RPC=$INDEXER_L1_ETH_RPC - - INDEXER_L2_ETH_RPC=$INDEXER_L2_ETH_RPC + - INDEXER_CHAIN_ID=${INDEXER_CHAIN_ID:-900} + - INDEXER_L1_ETH_RPC=http://192.168.43.166:8545 + - INDEXER_L2_ETH_RPC=http://192.168.43.166:9545 - INDEXER_REST_HOSTNAME=0.0.0.0 - INDEXER_REST_PORT=8080 - INDEXER_BEDROCK_L1_STANDARD_BRIDGE=0 - - INDEXER_BEDROCK_L1_STANDARD_BRIDGE=${INDEXER_BEDROCK_L1_STANDARD_BRIDGE:-0x636Af16bf2f682dD3109e60102b8E1A089FedAa8} - - INDEXER_BEDROCK_OPTIMISM_PORTAL=${INDEXER_BEDROCK_OPTIMISM_PORTAL:-0xB7040fd32359688346A3D1395a42114cf8E3b9b2} - - INDEXER_L1_ADDRESS_MANAGER_ADDRESS=${INDEXER_L1_ADDRESS_MANAGER_ADDRESS:-0xdE1FCfB0851916CA5101820A69b13a4E276bd81F} + - INDEXER_BEDROCK_L1_STANDARD_BRIDGE=${INDEXER_BEDROCK_L1_STANDARD_BRIDGE:-0x6900000000000000000000000000000000000003} + - INDEXER_BEDROCK_OPTIMISM_PORTAL=${INDEXER_BEDROCK_OPTIMISM_PORTAL:-0x6900000000000000000000000000000000000001} + - INDEXER_L1_ADDRESS_MANAGER_ADDRESS=${INDEXER_L1_ADDRESS_MANAGER_ADDRESS:-0x6900000000000000000000000000000000000005} ports: - 8080:8080 depends_on: postgres: condition: service_healthy - + ui: build: context: .. @@ -61,7 +61,7 @@ services: postgres: condition: service_healthy - prisma-check: + prisma-check: restart: "no" build: context: .. diff --git a/l2geth/tests/testdata b/l2geth/tests/testdata new file mode 160000 index 0000000000000..ff68495eb56c3 --- /dev/null +++ b/l2geth/tests/testdata @@ -0,0 +1 @@ +Subproject commit ff68495eb56c382b2ddcea4020259e106353b874 diff --git a/op-bindings/bindings/addressmanager.go b/op-bindings/bindings/addressmanager.go index c812c9c2c31d0..2cb3f53191310 100644 --- a/op-bindings/bindings/addressmanager.go +++ b/op-bindings/bindings/addressmanager.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // AddressManagerMetaData contains all meta data concerning the AddressManager contract. @@ -156,11 +157,11 @@ func NewAddressManagerFilterer(address common.Address, filterer bind.ContractFil // bindAddressManager binds a generic wrapper to an already deployed contract. func bindAddressManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(AddressManagerABI)) + parsed, err := AddressManagerMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/basefeevault.go b/op-bindings/bindings/basefeevault.go index de7a1622c800c..7f955bd7cbbc2 100644 --- a/op-bindings/bindings/basefeevault.go +++ b/op-bindings/bindings/basefeevault.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // BaseFeeVaultMetaData contains all meta data concerning the BaseFeeVault contract. @@ -156,11 +157,11 @@ func NewBaseFeeVaultFilterer(address common.Address, filterer bind.ContractFilte // bindBaseFeeVault binds a generic wrapper to an already deployed contract. func bindBaseFeeVault(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(BaseFeeVaultABI)) + parsed, err := BaseFeeVaultMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/deployerwhitelist.go b/op-bindings/bindings/deployerwhitelist.go index 1a0864a4060b7..0bd84000a8f69 100644 --- a/op-bindings/bindings/deployerwhitelist.go +++ b/op-bindings/bindings/deployerwhitelist.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // DeployerWhitelistMetaData contains all meta data concerning the DeployerWhitelist contract. @@ -156,11 +157,11 @@ func NewDeployerWhitelistFilterer(address common.Address, filterer bind.Contract // bindDeployerWhitelist binds a generic wrapper to an already deployed contract. func bindDeployerWhitelist(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(DeployerWhitelistABI)) + parsed, err := DeployerWhitelistMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/erc20.go b/op-bindings/bindings/erc20.go index 766f6eb69b117..3a5928324cb4c 100644 --- a/op-bindings/bindings/erc20.go +++ b/op-bindings/bindings/erc20.go @@ -26,12 +26,13 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // ERC20MetaData contains all meta data concerning the ERC20 contract. var ERC20MetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b5060405162000e3c38038062000e3c833981016040819052620000349162000127565b600362000042838262000220565b50600462000051828262000220565b505050620002ec565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200008257600080fd5b81516001600160401b03808211156200009f576200009f6200005a565b604051601f8301601f19908116603f01168101908282118183101715620000ca57620000ca6200005a565b81604052838152602092508683858801011115620000e757600080fd5b600091505b838210156200010b5785820183015181830184015290820190620000ec565b838211156200011d5760008385830101525b9695505050505050565b600080604083850312156200013b57600080fd5b82516001600160401b03808211156200015357600080fd5b620001618683870162000070565b935060208501519150808211156200017857600080fd5b50620001878582860162000070565b9150509250929050565b600181811c90821680620001a657607f821691505b602082108103620001c757634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200021b57600081815260208120601f850160051c81016020861015620001f65750805b601f850160051c820191505b81811015620002175782815560010162000202565b5050505b505050565b81516001600160401b038111156200023c576200023c6200005a565b62000254816200024d845462000191565b84620001cd565b602080601f8311600181146200028c5760008415620002735750858301515b600019600386901b1c1916600185901b17855562000217565b600085815260208120601f198616915b82811015620002bd578886015182559484019460019091019084016200029c565b5085821015620002dc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610b4080620002fc6000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80633950935111610081578063a457c2d71161005b578063a457c2d714610194578063a9059cbb146101a7578063dd62ed3e146101ba57600080fd5b8063395093511461014357806370a082311461015657806395d89b411461018c57600080fd5b806318160ddd116100b257806318160ddd1461010f57806323b872dd14610121578063313ce5671461013457600080fd5b806306fdde03146100ce578063095ea7b3146100ec575b600080fd5b6100d6610200565b6040516100e3919061094a565b60405180910390f35b6100ff6100fa3660046109e6565b610292565b60405190151581526020016100e3565b6002545b6040519081526020016100e3565b6100ff61012f366004610a10565b6102aa565b604051601281526020016100e3565b6100ff6101513660046109e6565b6102ce565b610113610164366004610a4c565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6100d661031a565b6100ff6101a23660046109e6565b610329565b6100ff6101b53660046109e6565b6103ff565b6101136101c8366004610a6e565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b60606003805461020f90610aa1565b80601f016020809104026020016040519081016040528092919081815260200182805461023b90610aa1565b80156102885780601f1061025d57610100808354040283529160200191610288565b820191906000526020600020905b81548152906001019060200180831161026b57829003601f168201915b5050505050905090565b6000336102a081858561040d565b5060019392505050565b6000336102b88582856105c0565b6102c3858585610697565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906102a09082908690610315908790610af4565b61040d565b60606004805461020f90610aa1565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190838110156103f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102c3828686840361040d565b6000336102a0818585610697565b73ffffffffffffffffffffffffffffffffffffffff83166104af576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff8216610552576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146106915781811015610684576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103e9565b610691848484840361040d565b50505050565b73ffffffffffffffffffffffffffffffffffffffff831661073a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff82166107dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610893576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016103e9565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152602081905260408082208585039055918516815290812080548492906108d7908490610af4565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161093d91815260200190565b60405180910390a3610691565b600060208083528351808285015260005b818110156109775785810183015185820160400152820161095b565b81811115610989576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146109e157600080fd5b919050565b600080604083850312156109f957600080fd5b610a02836109bd565b946020939093013593505050565b600080600060608486031215610a2557600080fd5b610a2e846109bd565b9250610a3c602085016109bd565b9150604084013590509250925092565b600060208284031215610a5e57600080fd5b610a67826109bd565b9392505050565b60008060408385031215610a8157600080fd5b610a8a836109bd565b9150610a98602084016109bd565b90509250929050565b600181811c90821680610ab557607f821691505b602082108103610aee577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008219821115610b2e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50019056fea164736f6c634300080f000a", + Bin: "0x60806040523480156200001157600080fd5b5060405162000e2a38038062000e2a83398101604081905262000034916200011f565b600362000042838262000218565b50600462000051828262000218565b505050620002e4565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200008257600080fd5b81516001600160401b03808211156200009f576200009f6200005a565b604051601f8301601f19908116603f01168101908282118183101715620000ca57620000ca6200005a565b81604052838152602092508683858801011115620000e757600080fd5b600091505b838210156200010b5785820183015181830184015290820190620000ec565b600093810190920192909252949350505050565b600080604083850312156200013357600080fd5b82516001600160401b03808211156200014b57600080fd5b620001598683870162000070565b935060208501519150808211156200017057600080fd5b506200017f8582860162000070565b9150509250929050565b600181811c908216806200019e57607f821691505b602082108103620001bf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200021357600081815260208120601f850160051c81016020861015620001ee5750805b601f850160051c820191505b818110156200020f57828155600101620001fa565b5050505b505050565b81516001600160401b038111156200023457620002346200005a565b6200024c8162000245845462000189565b84620001c5565b602080601f8311600181146200028457600084156200026b5750858301515b600019600386901b1c1916600185901b1785556200020f565b600085815260208120601f198616915b82811015620002b55788860151825594840194600190910190840162000294565b5085821015620002d45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610b3680620002f46000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80633950935111610081578063a457c2d71161005b578063a457c2d714610194578063a9059cbb146101a7578063dd62ed3e146101ba57600080fd5b8063395093511461014357806370a082311461015657806395d89b411461018c57600080fd5b806318160ddd116100b257806318160ddd1461010f57806323b872dd14610121578063313ce5671461013457600080fd5b806306fdde03146100ce578063095ea7b3146100ec575b600080fd5b6100d6610200565b6040516100e3919061094c565b60405180910390f35b6100ff6100fa3660046109e1565b610292565b60405190151581526020016100e3565b6002545b6040519081526020016100e3565b6100ff61012f366004610a0b565b6102ac565b604051601281526020016100e3565b6100ff6101513660046109e1565b6102d0565b610113610164366004610a47565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6100d661031c565b6100ff6101a23660046109e1565b61032b565b6100ff6101b53660046109e1565b610401565b6101136101c8366004610a69565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b60606003805461020f90610a9c565b80601f016020809104026020016040519081016040528092919081815260200182805461023b90610a9c565b80156102885780601f1061025d57610100808354040283529160200191610288565b820191906000526020600020905b81548152906001019060200180831161026b57829003601f168201915b5050505050905090565b6000336102a081858561040f565b60019150505b92915050565b6000336102ba8582856105c2565b6102c5858585610699565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906102a09082908690610317908790610aef565b61040f565b60606004805461020f90610a9c565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190838110156103f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6102c5828686840361040f565b6000336102a0818585610699565b73ffffffffffffffffffffffffffffffffffffffff83166104b1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016103eb565b73ffffffffffffffffffffffffffffffffffffffff8216610554576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016103eb565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146106935781811015610686576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103eb565b610693848484840361040f565b50505050565b73ffffffffffffffffffffffffffffffffffffffff831661073c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016103eb565b73ffffffffffffffffffffffffffffffffffffffff82166107df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016103eb565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610895576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016103eb565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152602081905260408082208585039055918516815290812080548492906108d9908490610aef565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161093f91815260200190565b60405180910390a3610693565b600060208083528351808285015260005b818110156109795785810183015185820160400152820161095d565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146109dc57600080fd5b919050565b600080604083850312156109f457600080fd5b6109fd836109b8565b946020939093013593505050565b600080600060608486031215610a2057600080fd5b610a29846109b8565b9250610a37602085016109b8565b9150604084013590509250925092565b600060208284031215610a5957600080fd5b610a62826109b8565b9392505050565b60008060408385031215610a7c57600080fd5b610a85836109b8565b9150610a93602084016109b8565b90509250929050565b600181811c90821680610ab057607f821691505b602082108103610ae9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b808201808211156102a6577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000811000a", } // ERC20ABI is the input ABI used to generate the binding from. @@ -156,11 +157,11 @@ func NewERC20Filterer(address common.Address, filterer bind.ContractFilterer) (* // bindERC20 binds a generic wrapper to an already deployed contract. func bindERC20(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ERC20ABI)) + parsed, err := ERC20MetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/gaspriceoracle.go b/op-bindings/bindings/gaspriceoracle.go index d2904367a11f1..2eacab901da8b 100644 --- a/op-bindings/bindings/gaspriceoracle.go +++ b/op-bindings/bindings/gaspriceoracle.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // GasPriceOracleMetaData contains all meta data concerning the GasPriceOracle contract. @@ -156,11 +157,11 @@ func NewGasPriceOracleFilterer(address common.Address, filterer bind.ContractFil // bindGasPriceOracle binds a generic wrapper to an already deployed contract. func bindGasPriceOracle(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(GasPriceOracleABI)) + parsed, err := GasPriceOracleMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/l1block.go b/op-bindings/bindings/l1block.go index 5d4c17def2471..507dc8d6f21d0 100644 --- a/op-bindings/bindings/l1block.go +++ b/op-bindings/bindings/l1block.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // L1BlockMetaData contains all meta data concerning the L1Block contract. @@ -156,11 +157,11 @@ func NewL1BlockFilterer(address common.Address, filterer bind.ContractFilterer) // bindL1Block binds a generic wrapper to an already deployed contract. func bindL1Block(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(L1BlockABI)) + parsed, err := L1BlockMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/l1blocknumber.go b/op-bindings/bindings/l1blocknumber.go index faf3c0f1e96f4..66b122edc3081 100644 --- a/op-bindings/bindings/l1blocknumber.go +++ b/op-bindings/bindings/l1blocknumber.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // L1BlockNumberMetaData contains all meta data concerning the L1BlockNumber contract. @@ -156,11 +157,11 @@ func NewL1BlockNumberFilterer(address common.Address, filterer bind.ContractFilt // bindL1BlockNumber binds a generic wrapper to an already deployed contract. func bindL1BlockNumber(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(L1BlockNumberABI)) + parsed, err := L1BlockNumberMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/l1crossdomainmessenger.go b/op-bindings/bindings/l1crossdomainmessenger.go index 74e9cbf3356c9..a6952102fd459 100644 --- a/op-bindings/bindings/l1crossdomainmessenger.go +++ b/op-bindings/bindings/l1crossdomainmessenger.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // L1CrossDomainMessengerMetaData contains all meta data concerning the L1CrossDomainMessenger contract. @@ -156,11 +157,11 @@ func NewL1CrossDomainMessengerFilterer(address common.Address, filterer bind.Con // bindL1CrossDomainMessenger binds a generic wrapper to an already deployed contract. func bindL1CrossDomainMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(L1CrossDomainMessengerABI)) + parsed, err := L1CrossDomainMessengerMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/l1erc721bridge.go b/op-bindings/bindings/l1erc721bridge.go index a12168bdd3c83..10968659067cd 100644 --- a/op-bindings/bindings/l1erc721bridge.go +++ b/op-bindings/bindings/l1erc721bridge.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // L1ERC721BridgeMetaData contains all meta data concerning the L1ERC721Bridge contract. @@ -156,11 +157,11 @@ func NewL1ERC721BridgeFilterer(address common.Address, filterer bind.ContractFil // bindL1ERC721Bridge binds a generic wrapper to an already deployed contract. func bindL1ERC721Bridge(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(L1ERC721BridgeABI)) + parsed, err := L1ERC721BridgeMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/l1feevault.go b/op-bindings/bindings/l1feevault.go index 733c0a2136201..1ec94e4c112d4 100644 --- a/op-bindings/bindings/l1feevault.go +++ b/op-bindings/bindings/l1feevault.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // L1FeeVaultMetaData contains all meta data concerning the L1FeeVault contract. @@ -156,11 +157,11 @@ func NewL1FeeVaultFilterer(address common.Address, filterer bind.ContractFiltere // bindL1FeeVault binds a generic wrapper to an already deployed contract. func bindL1FeeVault(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(L1FeeVaultABI)) + parsed, err := L1FeeVaultMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/l1standardbridge.go b/op-bindings/bindings/l1standardbridge.go index 3427d5d6360c2..3f75f062ad08d 100644 --- a/op-bindings/bindings/l1standardbridge.go +++ b/op-bindings/bindings/l1standardbridge.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // L1StandardBridgeMetaData contains all meta data concerning the L1StandardBridge contract. @@ -156,11 +157,11 @@ func NewL1StandardBridgeFilterer(address common.Address, filterer bind.ContractF // bindL1StandardBridge binds a generic wrapper to an already deployed contract. func bindL1StandardBridge(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(L1StandardBridgeABI)) + parsed, err := L1StandardBridgeMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/l2crossdomainmessenger.go b/op-bindings/bindings/l2crossdomainmessenger.go index 8dcd4967d34dc..09b3b061fc5a1 100644 --- a/op-bindings/bindings/l2crossdomainmessenger.go +++ b/op-bindings/bindings/l2crossdomainmessenger.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // L2CrossDomainMessengerMetaData contains all meta data concerning the L2CrossDomainMessenger contract. @@ -156,11 +157,11 @@ func NewL2CrossDomainMessengerFilterer(address common.Address, filterer bind.Con // bindL2CrossDomainMessenger binds a generic wrapper to an already deployed contract. func bindL2CrossDomainMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(L2CrossDomainMessengerABI)) + parsed, err := L2CrossDomainMessengerMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/l2erc721bridge.go b/op-bindings/bindings/l2erc721bridge.go index 4cb400dca97bf..3c74c587da496 100644 --- a/op-bindings/bindings/l2erc721bridge.go +++ b/op-bindings/bindings/l2erc721bridge.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // L2ERC721BridgeMetaData contains all meta data concerning the L2ERC721Bridge contract. @@ -156,11 +157,11 @@ func NewL2ERC721BridgeFilterer(address common.Address, filterer bind.ContractFil // bindL2ERC721Bridge binds a generic wrapper to an already deployed contract. func bindL2ERC721Bridge(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(L2ERC721BridgeABI)) + parsed, err := L2ERC721BridgeMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/l2outputoracle.go b/op-bindings/bindings/l2outputoracle.go index 0cd7507855ec7..604dedfdd7805 100644 --- a/op-bindings/bindings/l2outputoracle.go +++ b/op-bindings/bindings/l2outputoracle.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // TypesOutputProposal is an auto generated low-level Go binding around an user-defined struct. @@ -163,11 +164,11 @@ func NewL2OutputOracleFilterer(address common.Address, filterer bind.ContractFil // bindL2OutputOracle binds a generic wrapper to an already deployed contract. func bindL2OutputOracle(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(L2OutputOracleABI)) + parsed, err := L2OutputOracleMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/l2standardbridge.go b/op-bindings/bindings/l2standardbridge.go index 8c4c9c5bf9c85..6c88e897d2248 100644 --- a/op-bindings/bindings/l2standardbridge.go +++ b/op-bindings/bindings/l2standardbridge.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // L2StandardBridgeMetaData contains all meta data concerning the L2StandardBridge contract. @@ -156,11 +157,11 @@ func NewL2StandardBridgeFilterer(address common.Address, filterer bind.ContractF // bindL2StandardBridge binds a generic wrapper to an already deployed contract. func bindL2StandardBridge(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(L2StandardBridgeABI)) + parsed, err := L2StandardBridgeMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/l2tol1messagepasser.go b/op-bindings/bindings/l2tol1messagepasser.go index b2f7bf1de4689..1281222150a34 100644 --- a/op-bindings/bindings/l2tol1messagepasser.go +++ b/op-bindings/bindings/l2tol1messagepasser.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // L2ToL1MessagePasserMetaData contains all meta data concerning the L2ToL1MessagePasser contract. @@ -156,11 +157,11 @@ func NewL2ToL1MessagePasserFilterer(address common.Address, filterer bind.Contra // bindL2ToL1MessagePasser binds a generic wrapper to an already deployed contract. func bindL2ToL1MessagePasser(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(L2ToL1MessagePasserABI)) + parsed, err := L2ToL1MessagePasserMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/legacyerc20eth.go b/op-bindings/bindings/legacyerc20eth.go index 71f0588fedc82..6e63fb359cf20 100644 --- a/op-bindings/bindings/legacyerc20eth.go +++ b/op-bindings/bindings/legacyerc20eth.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // LegacyERC20ETHMetaData contains all meta data concerning the LegacyERC20ETH contract. @@ -156,11 +157,11 @@ func NewLegacyERC20ETHFilterer(address common.Address, filterer bind.ContractFil // bindLegacyERC20ETH binds a generic wrapper to an already deployed contract. func bindLegacyERC20ETH(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(LegacyERC20ETHABI)) + parsed, err := LegacyERC20ETHMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/legacymessagepasser.go b/op-bindings/bindings/legacymessagepasser.go index d3745941bc2eb..1a1bb0b3245f2 100644 --- a/op-bindings/bindings/legacymessagepasser.go +++ b/op-bindings/bindings/legacymessagepasser.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // LegacyMessagePasserMetaData contains all meta data concerning the LegacyMessagePasser contract. @@ -156,11 +157,11 @@ func NewLegacyMessagePasserFilterer(address common.Address, filterer bind.Contra // bindLegacyMessagePasser binds a generic wrapper to an already deployed contract. func bindLegacyMessagePasser(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(LegacyMessagePasserABI)) + parsed, err := LegacyMessagePasserMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/optimismmintableerc20.go b/op-bindings/bindings/optimismmintableerc20.go index 6c9bbb4d25aa8..5365eb7a2bdc2 100644 --- a/op-bindings/bindings/optimismmintableerc20.go +++ b/op-bindings/bindings/optimismmintableerc20.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // OptimismMintableERC20MetaData contains all meta data concerning the OptimismMintableERC20 contract. @@ -156,11 +157,11 @@ func NewOptimismMintableERC20Filterer(address common.Address, filterer bind.Cont // bindOptimismMintableERC20 binds a generic wrapper to an already deployed contract. func bindOptimismMintableERC20(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(OptimismMintableERC20ABI)) + parsed, err := OptimismMintableERC20MetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/optimismmintableerc20factory.go b/op-bindings/bindings/optimismmintableerc20factory.go index be99e2c4e69da..565fb54f777df 100644 --- a/op-bindings/bindings/optimismmintableerc20factory.go +++ b/op-bindings/bindings/optimismmintableerc20factory.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // OptimismMintableERC20FactoryMetaData contains all meta data concerning the OptimismMintableERC20Factory contract. @@ -156,11 +157,11 @@ func NewOptimismMintableERC20FactoryFilterer(address common.Address, filterer bi // bindOptimismMintableERC20Factory binds a generic wrapper to an already deployed contract. func bindOptimismMintableERC20Factory(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(OptimismMintableERC20FactoryABI)) + parsed, err := OptimismMintableERC20FactoryMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/optimismmintableerc721factory.go b/op-bindings/bindings/optimismmintableerc721factory.go index 494861c9dc95a..5188bd1f3f90e 100644 --- a/op-bindings/bindings/optimismmintableerc721factory.go +++ b/op-bindings/bindings/optimismmintableerc721factory.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // OptimismMintableERC721FactoryMetaData contains all meta data concerning the OptimismMintableERC721Factory contract. @@ -156,11 +157,11 @@ func NewOptimismMintableERC721FactoryFilterer(address common.Address, filterer b // bindOptimismMintableERC721Factory binds a generic wrapper to an already deployed contract. func bindOptimismMintableERC721Factory(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(OptimismMintableERC721FactoryABI)) + parsed, err := OptimismMintableERC721FactoryMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/optimismportal.go b/op-bindings/bindings/optimismportal.go index a1980ea687bfe..7af7d480f96fb 100644 --- a/op-bindings/bindings/optimismportal.go +++ b/op-bindings/bindings/optimismportal.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // TypesOutputRootProof is an auto generated low-level Go binding around an user-defined struct. @@ -48,8 +49,8 @@ type TypesWithdrawalTransaction struct { // OptimismPortalMetaData contains all meta data concerning the OptimismPortal contract. var OptimismPortalMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"_l2Oracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_guardian\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_paused\",\"type\":\"bool\"},{\"internalType\":\"contractSystemConfig\",\"name\":\"_config\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"opaqueData\",\"type\":\"bytes\"}],\"name\":\"TransactionDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"WithdrawalFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"WithdrawalProven\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"GUARDIAN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_ORACLE\",\"outputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SYSTEM_CONFIG\",\"outputs\":[{\"internalType\":\"contractSystemConfig\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"_isCreation\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"donateETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"}],\"name\":\"finalizeWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"finalizedWithdrawals\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_paused\",\"type\":\"bool\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"name\":\"isOutputFinalized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Sender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_byteCount\",\"type\":\"uint64\"}],\"name\":\"minimumGasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"params\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"prevBaseFee\",\"type\":\"uint128\"},{\"internalType\":\"uint64\",\"name\":\"prevBoughtGas\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"prevBlockNum\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"messagePasserStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}],\"internalType\":\"structTypes.OutputRootProof\",\"name\":\"_outputRootProof\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"_withdrawalProof\",\"type\":\"bytes[]\"}],\"name\":\"proveWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"provenWithdrawals\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2OutputIndex\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", - Bin: "0x6101406040523480156200001257600080fd5b50604051620059c8380380620059c8833981016040819052620000359162000296565b60016080819052600760a05260c0526001600160a01b0380851660e052838116610120528116610100526200006a8262000074565b5050505062000302565b600054610100900460ff1615808015620000955750600054600160ff909116105b80620000c55750620000b230620001cb60201b62001c891760201c565b158015620000c5575060005460ff166001145b6200012e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000152576000805461ff0019166101001790555b603280546001600160a01b03191661dead1790556035805483151560ff1990911617905562000180620001da565b8015620001c7576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b600054610100900460ff16620002475760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000125565b60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b6001600160a01b03811681146200029357600080fd5b50565b60008060008060808587031215620002ad57600080fd5b8451620002ba816200027d565b6020860151909450620002cd816200027d565b60408601519093508015158114620002e457600080fd5b6060860151909250620002f7816200027d565b939692955090935050565b60805160a05160c05160e051610100516101205161563762000391600039600081816102690152818161079d01526110a00152600081816104c801526123d701526000818161016a01528181610a0601528181610be701528181610ffc015281816113b60152818161162801526121c301526000610f6701526000610f3e01526000610f1501526156376000f3fe60806040526004361061012c5760003560e01c80638c3152e9116100a5578063cff0ab9611610074578063e965084c11610059578063e965084c14610417578063e9e05c42146104a3578063f0498750146104b657600080fd5b8063cff0ab9614610356578063d53a822f146103f757600080fd5b80638c3152e9146102a05780639bf62d82146102c0578063a14238e7146102ed578063a35d99df1461031d57600080fd5b80635c975abb116100fc578063724c184c116100e1578063724c184c146102575780638456cb591461028b5780638b4c40b01461015157600080fd5b80635c975abb1461020d5780636dbffb781461023757600080fd5b80621c2ff6146101585780633f4ba83a146101b65780634870496f146101cb57806354fd4d50146101eb57600080fd5b36610153576101513334620186a06000604051806020016040528060008152506104ea565b005b600080fd5b34801561016457600080fd5b5061018c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101c257600080fd5b50610151610785565b3480156101d757600080fd5b506101516101e6366004614be9565b6108a8565b3480156101f757600080fd5b50610200610f0e565b6040516101ad9190614d3f565b34801561021957600080fd5b506035546102279060ff1681565b60405190151581526020016101ad565b34801561024357600080fd5b50610227610252366004614d52565b610fb1565b34801561026357600080fd5b5061018c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561029757600080fd5b50610151611088565b3480156102ac57600080fd5b506101516102bb366004614d6b565b6111a8565b3480156102cc57600080fd5b5060325461018c9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102f957600080fd5b50610227610308366004614d52565b60336020526000908152604090205460ff1681565b34801561032957600080fd5b5061033d610338366004614db8565b611a83565b60405167ffffffffffffffff90911681526020016101ad565b34801561036257600080fd5b506001546103be906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101ad565b34801561040357600080fd5b50610151610412366004614de3565b611a9c565b34801561042357600080fd5b50610475610432366004614d52565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101ad565b6101516104b1366004614dfe565b6104ea565b3480156104c257600080fd5b5061018c7f000000000000000000000000000000000000000000000000000000000000000081565b8260005a905083156105a15773ffffffffffffffffffffffffffffffffffffffff8716156105a157604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6105ab8351611a83565b67ffffffffffffffff168567ffffffffffffffff16101561064e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c00000000000000000000000000000000000000000000000000000000006064820152608401610598565b6201d4c0835111156106bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c6172676500006044820152606401610598565b333281146106dd575033731111000000000000000000000000000000001111015b600034888888886040516020016106f8959493929190614e77565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516107689190614d3f565b60405180910390a4505061077c8282611ca5565b50505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461084a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e706175736500000000000000000000000000000000000000000000006064820152608401610598565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff1615610915576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610598565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610598565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a869190614efc565b519050610aa0610a9b36869003860186614f61565b611fd2565b8114610b2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610598565b6000610b398761202e565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c6b5750805160408083015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c679190614efc565b5114155b610cf7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610598565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610dc09101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610db6888a614fc7565b8a6040013561205e565b610e4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610598565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6060610f397f0000000000000000000000000000000000000000000000000000000000000000612082565b610f627f0000000000000000000000000000000000000000000000000000000000000000612082565b610f8b7f0000000000000000000000000000000000000000000000000000000000000000612082565b604051602001610f9d9392919061504b565b604051602081830303815290604052905090565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018290526000906110829073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa158015611043573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110679190614efc565b602001516fffffffffffffffffffffffffffffffff166121bf565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461114d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e207061757365000000000000000000000000000000000000000000000000006064820152608401610598565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200161089e565b60355460ff1615611215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610598565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead146112be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610598565b60006112c98261202e565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff808216948301859052700100000000000000000000000000000000909104169181019190915292935090036113b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610598565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa15801561141f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144391906150c1565b81602001516fffffffffffffffffffffffffffffffff16101561150e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610598565b61152d81602001516fffffffffffffffffffffffffffffffff166121bf565b6115df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610598565b60408181015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015611684573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a89190614efc565b8251815191925014611762576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610598565b61178181602001516fffffffffffffffffffffffffffffffff166121bf565b611833576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610598565b60008381526033602052604090205460ff16156118d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610598565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a088015161197493929190612262565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b906119d990841515815260200190565b60405180910390a2801580156119ef5750326001145b15611a7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610598565b5050505050565b6000611a90826010615109565b61108290615208615139565b600054610100900460ff1615808015611abc5750600054600160ff909116105b80611ad65750303b158015611ad6575060005460ff166001145b611b62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610598565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611bc057600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055603580548315157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055611c226122c0565b8015611c8557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600154600090611cdb907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643615165565b90506000611ce76123a3565b90506000816020015160ff16826000015163ffffffff16611d0891906151ab565b90508215611e3f57600154600090611d3f908390700100000000000000000000000000000000900467ffffffffffffffff16615213565b90506000836040015160ff1683611d569190615287565b600154611d769084906fffffffffffffffffffffffffffffffff16615287565b611d8091906151ab565b600154909150600090611dd190611daa9084906fffffffffffffffffffffffffffffffff16615343565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612469565b90506001861115611e0057611dfd611daa82876040015160ff1660018a611df89190615165565b612488565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611e72908490700100000000000000000000000000000000900467ffffffffffffffff16615139565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611f55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d697400006064820152608401610598565b600154600090611f81906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166153b7565b90506000611f9348633b9aca006124dd565b611f9d90836153f4565b905060005a611fac9088615165565b905080821115611fc857611fc8611fc38284615165565b6124f4565b5050505050505050565b60008160000151826020015183604001518460600151604051602001612011949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097612011979096959101615408565b60008061206a86612522565b905061207881868686612554565b9695505050505050565b6060816000036120c557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156120ef57806120d98161545f565b91506120e89050600a836153f4565b91506120c9565b60008167ffffffffffffffff81111561210a5761210a614a0f565b6040519080825280601f01601f191660200182016040528015612134576020820181803683370190505b5090505b84156121b757612149600183615165565b9150612156600a86615497565b6121619060306154ab565b60f81b818381518110612176576121766154c3565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506121b0600a866153f4565b9450612138565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561222c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225091906150c1565b61225a90836154ab565b421192915050565b6000806000612272866000612584565b9050806122a8576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff16612357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610598565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663cc731b026040518163ffffffff1660e01b815260040160c060405180830381865afa158015612440573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124649190615517565b905090565b600061247e61247885856125a2565b836125b2565b90505b9392505050565b6000670de0b6b3a76400006124c96124a085836151ab565b6124b290670de0b6b3a7640000615213565b6124c485670de0b6b3a7640000615287565b6125c1565b6124d39086615287565b61247e91906151ab565b6000818310156124ed5781612481565b5090919050565b6000805a90505b825a6125079083615165565b101561251d576125168261545f565b91506124fb565b505050565b6060818051906020012060405160200161253e91815260200190565b6040516020818303038152906040529050919050565b600061257b846125658786866125f2565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156124ed5781612481565b60008183126124ed5781612481565b6000612481670de0b6b3a7640000836125d98661307a565b6125e39190615287565b6125ed91906151ab565b6132be565b6060600084511161265f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610598565b600061266a846134fd565b90506000612677866135ec565b905060008460405160200161268e91815260200190565b60405160208183030381529060405290506000805b8451811015612ff15760008582815181106126c0576126c06154c3565b60200260200101519050845183111561275b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610598565b8260000361281457805180516020918201206040516127a99261278392910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b61280f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610598565b61296b565b8051516020116128ca578051805160209182012060405161283e9261278392910190815260200190565b61280f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610598565b80518451602080870191909120825191909201201461296b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610598565b612977601060016154ab565b81602001515103612b585784518303612af05760006129b382602001516010815181106129a6576129a66154c3565b602002602001015161364f565b90506000815111612a46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610598565b60018751612a549190615165565b8314612ae2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610598565b965061248195505050505050565b6000858481518110612b0457612b046154c3565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612b2f57612b2f6154c3565b60200260200101519050612b42816137af565b9550612b4f6001866154ab565b94505050612fde565b600281602001515103612f56576000612b70826137d4565b9050600081600081518110612b8757612b876154c3565b016020015160f81c90506000612b9e6002836155b6565b612ba99060026155d8565b90506000612bba848360ff166137f8565b90506000612bc88a896137f8565b90506000612bd6838361382e565b905080835114612c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610598565b60ff851660021480612c7d575060ff85166003145b15612e715780825114612d12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610598565b6000612d2e88602001516001815181106129a6576129a66154c3565b90506000815111612dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610598565b60018d51612dcf9190615165565b8914612e5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610598565b9c506124819b505050505050505050505050565b60ff85161580612e84575060ff85166001145b15612ec357612eb08760200151600181518110612ea357612ea36154c3565b60200260200101516137af565b9950612ebc818a6154ab565b9850612f4b565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610598565b505050505050612fde565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610598565b5080612fe98161545f565b9150506126a3565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610598565b60008082136130e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610598565b600060606130f2846138dd565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136132ef57506000919050565b680755bf798b4a1bf1e58212613361576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610598565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b805160609060008167ffffffffffffffff81111561351d5761351d614a0f565b60405190808252806020026020018201604052801561356257816020015b604080518082019091526060808252602082015281526020019060019003908161353b5790505b50905060005b828110156135e457604051806040016040528086838151811061358d5761358d6154c3565b602002602001015181526020016135bc8784815181106135af576135af6154c3565b60200260200101516139b3565b8152508282815181106135d1576135d16154c3565b6020908102919091010152600101613568565b509392505050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613644578060011b82018184015160001a8060041c8253600f811660018301535050600101613616565b509295945050505050565b6060600080600061365f856139c6565b91945092509050600081600181111561367a5761367a6155fb565b14613707576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d000000000000006064820152608401610598565b61371182846154ab565b8551146137a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e6465720000000000000000000000006064820152608401610598565b61257b85602001518484614433565b606060208260000151106137cb576137c68261364f565b611082565b611082826144d4565b60606110826137f383602001516000815181106129a6576129a66154c3565b6135ec565b6060825182106138175750604080516020810190915260008152611082565b61248183838486516138299190615165565b6144ea565b60008060008351855110613843578351613846565b84515b90505b80821080156138cd5750838281518110613865576138656154c3565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168583815181106138a4576138a46154c3565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156135e457816001019150613849565b6000808211613948576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610598565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b60606110826139c1836146c2565b6147ab565b600080600080846000015111613a84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610598565b6020840151805160001a607f8111613aa957600060016000945094509450505061442c565b60b78111613cb7576000613abe608083615165565b905080876000015111613b79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a401610598565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613bf257507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613ca4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a401610598565b506001955093506000925061442c915050565b60bf8111614005576000613ccc60b783615165565b905080876000015111613d87576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a401610598565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613e65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a401610598565b600184015160088302610100031c60378111613f29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a401610598565b613f3381846154ab565b895111613fe8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a401610598565b613ff38360016154ab565b975095506000945061442c9350505050565b60f781116140e657600061401a60c083615165565b9050808760000151116140d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a401610598565b60019550935084925061442c915050565b60006140f360f783615165565b9050808760000151116141ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a401610598565b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361428c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a401610598565b600184015160088302610100031c60378111614350576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a401610598565b61435a81846154ab565b89511161440f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a401610598565b61441a8360016154ab565b975095506001945061442c9350505050565b9193909250565b606060008267ffffffffffffffff81111561445057614450614a0f565b6040519080825280601f01601f19166020018201604052801561447a576020820181803683370190505b5090508260000361448c579050612481565b600061449885876154ab565b90506020820160005b858110156144b95782810151828201526020016144a1565b858111156144c8576000868301525b50919695505050505050565b6060611082826020015160008460000151614433565b60608182601f011015614559576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610598565b8282840110156145c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610598565b81830184511015614632576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610598565b60608215801561465157604051915060008252602082016040526146b9565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561468a578051835260209283019201614672565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b6040805180820190915260008082526020820152600082511161478d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610598565b50604080518082019091528151815260209182019181019190915290565b606060008060006147bb856139c6565b9194509250905060018160018111156147d6576147d66155fb565b14614863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d00000000000000006064820152608401610598565b845161486f83856154ab565b146148fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e64657200000000000000000000000000006064820152608401610598565b6040805160208082526104208201909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816149155790505090506000845b8751811015614a03576000806149886040518060400160405280858d6000015161496c9190615165565b8152602001858d6020015161498191906154ab565b90526139c6565b5091509150604051806040016040528083836149a491906154ab565b8152602001848c602001516149b991906154ab565b8152508585815181106149ce576149ce6154c3565b60209081029190910101526149e46001856154ab565b93506149f081836154ab565b6149fa90846154ab565b92505050614942565b50815295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614a8557614a85614a0f565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114614ab157600080fd5b919050565b600082601f830112614ac757600080fd5b813567ffffffffffffffff811115614ae157614ae1614a0f565b614b1260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a3e565b818152846020838601011115614b2757600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614b5657600080fd5b60405160c0810167ffffffffffffffff8282108183111715614b7a57614b7a614a0f565b8160405282935084358352614b9160208601614a8d565b6020840152614ba260408601614a8d565b6040840152606085013560608401526080850135608084015260a0850135915080821115614bcf57600080fd5b50614bdc85828601614ab6565b60a0830152505092915050565b600080600080600085870360e0811215614c0257600080fd5b863567ffffffffffffffff80821115614c1a57600080fd5b614c268a838b01614b44565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614c5f57600080fd5b60408901955060c0890135925080831115614c7957600080fd5b828901925089601f840112614c8d57600080fd5b8235915080821115614c9e57600080fd5b508860208260051b8401011115614cb457600080fd5b959894975092955050506020019190565b60005b83811015614ce0578181015183820152602001614cc8565b83811115614cef576000848401525b50505050565b60008151808452614d0d816020860160208601614cc5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006124816020830184614cf5565b600060208284031215614d6457600080fd5b5035919050565b600060208284031215614d7d57600080fd5b813567ffffffffffffffff811115614d9457600080fd5b6121b784828501614b44565b803567ffffffffffffffff81168114614ab157600080fd5b600060208284031215614dca57600080fd5b61248182614da0565b80358015158114614ab157600080fd5b600060208284031215614df557600080fd5b61248182614dd3565b600080600080600060a08688031215614e1657600080fd5b614e1f86614a8d565b945060208601359350614e3460408701614da0565b9250614e4260608701614dd3565b9150608086013567ffffffffffffffff811115614e5e57600080fd5b614e6a88828901614ab6565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614ecb816049850160208701614cc5565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614ab157600080fd5b600060608284031215614f0e57600080fd5b6040516060810181811067ffffffffffffffff82111715614f3157614f31614a0f565b60405282518152614f4460208401614edc565b6020820152614f5560408401614edc565b60408201529392505050565b600060808284031215614f7357600080fd5b6040516080810181811067ffffffffffffffff82111715614f9657614f96614a0f565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614fe257614fe2614a0f565b8360051b6020614ff3818301614a3e565b86815291850191818101903684111561500b57600080fd5b865b8481101561503f578035868111156150255760008081fd5b61503136828b01614ab6565b84525091830191830161500d565b50979650505050505050565b6000845161505d818460208901614cc5565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551615099816001850160208a01614cc5565b600192019182015283516150b4816002840160208801614cc5565b0160020195945050505050565b6000602082840312156150d357600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615615130576151306150da565b02949350505050565b600067ffffffffffffffff80831681851680830382111561515c5761515c6150da565b01949350505050565b600082821015615177576151776150da565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826151ba576151ba61517c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561520e5761520e6150da565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561524d5761524d6150da565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018313811615615281576152816150da565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156152c8576152c86150da565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615303576153036150da565b6000871292508782058712848416161561531f5761531f6150da565b87850587128184161615615335576153356150da565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561537d5761537d6150da565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156153b1576153b16150da565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156153ef576153ef6150da565b500290565b6000826154035761540361517c565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261545360c0830184614cf5565b98975050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615490576154906150da565b5060010190565b6000826154a6576154a661517c565b500690565b600082198211156154be576154be6150da565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b805163ffffffff81168114614ab157600080fd5b805160ff81168114614ab157600080fd5b600060c0828403121561552957600080fd5b60405160c0810181811067ffffffffffffffff8211171561554c5761554c614a0f565b604052615558836154f2565b815261556660208401615506565b602082015261557760408401615506565b6040820152615588606084016154f2565b6060820152615599608084016154f2565b60808201526155aa60a08401614edc565b60a08201529392505050565b600060ff8316806155c9576155c961517c565b8060ff84160691505092915050565b600060ff821660ff8416808210156155f2576155f26150da565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"_l2Oracle\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_guardian\",\"type\":\"address\"},{\"internalType\":\"contractSystemConfig\",\"name\":\"_config\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"version\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"opaqueData\",\"type\":\"bytes\"}],\"name\":\"TransactionDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"WithdrawalFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"WithdrawalProven\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"GUARDIAN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_ORACLE\",\"outputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SYSTEM_CONFIG\",\"outputs\":[{\"internalType\":\"contractSystemConfig\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"_gasLimit\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"_isCreation\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"donateETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"}],\"name\":\"finalizeWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"finalizedWithdrawals\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_paused\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_l1Messenger\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"}],\"name\":\"isOutputFinalized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l1Messenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2Sender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_byteCount\",\"type\":\"uint64\"}],\"name\":\"minimumGasLimit\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"params\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"prevBaseFee\",\"type\":\"uint128\"},{\"internalType\":\"uint64\",\"name\":\"prevBoughtGas\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"prevBlockNum\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structTypes.WithdrawalTransaction\",\"name\":\"_tx\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_l2OutputIndex\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"messagePasserStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}],\"internalType\":\"structTypes.OutputRootProof\",\"name\":\"_outputRootProof\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"_withdrawalProof\",\"type\":\"bytes[]\"}],\"name\":\"proveWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"provenWithdrawals\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"outputRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"timestamp\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"l2OutputIndex\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x6101406040523480156200001257600080fd5b50604051620058cd380380620058cd83398101604081905262000035916200007d565b60016080819052600760a05260c0526001600160a01b0392831660e052908216610120521661010052620000d1565b6001600160a01b03811681146200007a57600080fd5b50565b6000806000606084860312156200009357600080fd5b8351620000a08162000064565b6020850151909350620000b38162000064565b6040850151909250620000c68162000064565b809150509250925092565b60805160a05160c05160e051610100516101205161576d62000160600039600081816102b601528181610897015261119a01526000818161051501526124fa01526000818161018501528181610b0001528181610ce1015281816110f6015281816116e20152818161195401526122e601526000611061015260006110380152600061100f015261576d6000f3fe6080604052600436106101475760003560e01c806385ee7ba6116100c0578063a35d99df11610074578063e965084c11610059578063e965084c14610464578063e9e05c42146104f0578063f04987501461050357600080fd5b8063a35d99df1461038a578063cff0ab96146103c357600080fd5b80638c3152e9116100a55780638c3152e91461030d5780639bf62d821461032d578063a14238e71461035a57600080fd5b806385ee7ba6146102ed5780638b4c40b01461016c57600080fd5b80635c975abb116101175780636dbffb78116100fc5780636dbffb7814610284578063724c184c146102a45780638456cb59146102d857600080fd5b80635c975abb146102285780636140e0e61461025257600080fd5b80621c2ff6146101735780633f4ba83a146101d15780634870496f146101e657806354fd4d501461020657600080fd5b3661016e5761016c3334620186a0600060405180602001604052806000815250610537565b005b600080fd5b34801561017f57600080fd5b506101a77f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101dd57600080fd5b5061016c61087f565b3480156101f257600080fd5b5061016c610201366004614d07565b6109a2565b34801561021257600080fd5b5061021b611008565b6040516101c89190614e5d565b34801561023457600080fd5b506035546102429060ff1681565b60405190151581526020016101c8565b34801561025e57600080fd5b506035546101a790610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561029057600080fd5b5061024261029f366004614e70565b6110ab565b3480156102b057600080fd5b506101a77f000000000000000000000000000000000000000000000000000000000000000081565b3480156102e457600080fd5b5061016c611182565b3480156102f957600080fd5b5061016c610308366004614e99565b6112a2565b34801561031957600080fd5b5061016c610328366004614ecc565b6114d4565b34801561033957600080fd5b506032546101a79073ffffffffffffffffffffffffffffffffffffffff1681565b34801561036657600080fd5b50610242610375366004614e70565b60336020526000908152604090205460ff1681565b34801561039657600080fd5b506103aa6103a5366004614f19565b611daf565b60405167ffffffffffffffff90911681526020016101c8565b3480156103cf57600080fd5b5060015461042b906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101c8565b34801561047057600080fd5b506104c261047f366004614e70565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101c8565b61016c6104fe366004614f34565b610537565b34801561050f57600080fd5b506101a77f000000000000000000000000000000000000000000000000000000000000000081565b8260005a603554909150610100900473ffffffffffffffffffffffffffffffffffffffff1633146105ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f6d657373656e67657220636f6e747261637420756e61757468656e746963617460448201527f656400000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b831561069b5773ffffffffffffffffffffffffffffffffffffffff87161561069b57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084016105e6565b6106a58351611daf565b67ffffffffffffffff168567ffffffffffffffff161015610748576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c000000000000000000000000000000000000000000000000000000000060648201526084016105e6565b6201d4c0835111156107b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c61726765000060448201526064016105e6565b333281146107d7575033731111000000000000000000000000000000001111015b600034888888886040516020016107f2959493929190614fad565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516108629190614e5d565b60405180910390a450506108768282611dc8565b50505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610944576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e7061757365000000000000000000000000000000000000000000000060648201526084016105e6565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff1615610a0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a207061757365640000000000000000000060448201526064016105e6565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff1603610ace576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e74726163740060648201526084016105e6565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610b5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b809190615032565b519050610b9a610b9536869003860186615097565b6120f5565b8114610c28576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f66000000000000000000000000000000000000000000000060648201526084016105e6565b6000610c3387612151565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610d655750805160408083015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d619190615032565b5114155b610df1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e00000000000000000060648201526084016105e6565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610eba9101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610eb0888a6150fd565b8a60400135612181565b610f46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f66000000000000000000000000000060648201526084016105e6565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b60606110337f00000000000000000000000000000000000000000000000000000000000000006121a5565b61105c7f00000000000000000000000000000000000000000000000000000000000000006121a5565b6110857f00000000000000000000000000000000000000000000000000000000000000006121a5565b60405160200161109793929190615181565b604051602081830303815290604052905090565b6040517fa25ae5570000000000000000000000000000000000000000000000000000000081526004810182905260009061117c9073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa15801561113d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111619190615032565b602001516fffffffffffffffffffffffffffffffff166122e2565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611247576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e2070617573650000000000000000000000000000000000000000000000000060648201526084016105e6565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610998565b600054610100900460ff16158080156112c25750600054600160ff909116105b806112dc5750303b1580156112dc575060005460ff166001145b611368576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105e6565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156113c657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055603580548415157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055611428612385565b603580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1661010073ffffffffffffffffffffffffffffffffffffffff85160217905580156114cf57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60355460ff1615611541576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a207061757365640000000000000000000060448201526064016105e6565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead146115ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e0060648201526084016105e6565b60006115f582612151565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff808216948301859052700100000000000000000000000000000000909104169181019190915292935090036116e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e20796574000000000000000000000000000060648201526084016105e6565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa15801561174b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176f91906151f7565b81602001516fffffffffffffffffffffffffffffffff16101561183a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a4016105e6565b61185981602001516fffffffffffffffffffffffffffffffff166122e2565b61190b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a4016105e6565b60408181015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa1580156119b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119d49190615032565b8251815191925014611a8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a4016105e6565b611aad81602001516fffffffffffffffffffffffffffffffff166122e2565b611b5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a4016105e6565b60008381526033602052604090205460ff1615611bfe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a6564000000000000000000000060648201526084016105e6565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a0880151611ca093929190612468565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b90611d0590841515815260200190565b60405180910390a280158015611d1b5750326001145b15611da8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f640000000000000000000000000000000000000000000000000000000000000060648201526084016105e6565b5050505050565b6000611dbc82601061523f565b61117c9061520861526f565b600154600090611dfe907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361529b565b90506000611e0a6124c6565b90506000816020015160ff16826000015163ffffffff16611e2b91906152e1565b90508215611f6257600154600090611e62908390700100000000000000000000000000000000900467ffffffffffffffff16615349565b90506000836040015160ff1683611e7991906153bd565b600154611e999084906fffffffffffffffffffffffffffffffff166153bd565b611ea391906152e1565b600154909150600090611ef490611ecd9084906fffffffffffffffffffffffffffffffff16615479565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff1661258c565b90506001861115611f2357611f20611ecd82876040015160ff1660018a611f1b919061529b565b6125ab565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611f95908490700100000000000000000000000000000000900467ffffffffffffffff1661526f565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315612078576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d6974000060648201526084016105e6565b6001546000906120a4906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166154ed565b905060006120b648633b9aca00612600565b6120c0908361552a565b905060005a6120cf908861529b565b9050808211156120eb576120eb6120e6828461529b565b612617565b5050505050505050565b60008160000151826020015183604001518460600151604051602001612134949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a0880151935160009761213497909695910161553e565b60008061218d86612640565b905061219b81868686612672565b9695505050505050565b6060816000036121e857505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561221257806121fc81615595565b915061220b9050600a8361552a565b91506121ec565b60008167ffffffffffffffff81111561222d5761222d614b2d565b6040519080825280601f01601f191660200182016040528015612257576020820181803683370190505b5090505b84156122da5761226c60018361529b565b9150612279600a866155cd565b6122849060306155e1565b60f81b818381518110612299576122996155f9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506122d3600a8661552a565b945061225b565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561234f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237391906151f7565b61237d90836155e1565b421192915050565b600054610100900460ff1661241c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105e6565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b60008060006124788660006126a2565b9050806124ae576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663cc731b026040518163ffffffff1660e01b815260040160c060405180830381865afa158015612563573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612587919061564d565b905090565b60006125a161259b85856126c0565b836126d0565b90505b9392505050565b6000670de0b6b3a76400006125ec6125c385836152e1565b6125d590670de0b6b3a7640000615349565b6125e785670de0b6b3a76400006153bd565b6126df565b6125f690866153bd565b6125a191906152e1565b60008183101561261057816125a4565b5090919050565b6000805a90505b825a61262a908361529b565b10156114cf5761263982615595565b915061261e565b6060818051906020012060405160200161265c91815260200190565b6040516020818303038152906040529050919050565b600061269984612683878686612710565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b60008183121561261057816125a4565b600081831261261057816125a4565b60006125a4670de0b6b3a7640000836126f786613198565b61270191906153bd565b61270b91906152e1565b6133dc565b6060600084511161277d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b6579000000000000000000000060448201526064016105e6565b60006127888461361b565b905060006127958661370a565b90506000846040516020016127ac91815260200190565b60405160208183030381529060405290506000805b845181101561310f5760008582815181106127de576127de6155f9565b602002602001015190508451831115612879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e67746800000000000000000000000000000000000060648201526084016105e6565b8260000361293257805180516020918201206040516128c7926128a192910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b61292d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f74206861736800000060448201526064016105e6565b612a89565b8051516020116129e8578051805160209182012060405161295c926128a192910190815260200190565b61292d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c20686173680000000000000000000000000000000000000000000000000060648201526084016105e6565b805184516020808701919091208251919092012014612a89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f652068617368000000000000000000000000000000000000000000000000000060648201526084016105e6565b612a95601060016155e1565b81602001515103612c765784518303612c0e576000612ad18260200151601081518110612ac457612ac46155f9565b602002602001015161376d565b90506000815111612b64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e636829000000000060648201526084016105e6565b60018751612b72919061529b565b8314612c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e63682900000000000060648201526084016105e6565b96506125a495505050505050565b6000858481518110612c2257612c226155f9565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612c4d57612c4d6155f9565b60200260200101519050612c60816138cd565b9550612c6d6001866155e1565b945050506130fc565b600281602001515103613074576000612c8e826138f2565b9050600081600081518110612ca557612ca56155f9565b016020015160f81c90506000612cbc6002836156ec565b612cc790600261570e565b90506000612cd8848360ff16613916565b90506000612ce68a89613916565b90506000612cf4838361394c565b905080835114612d86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b657900000000000060648201526084016105e6565b60ff851660021480612d9b575060ff85166003145b15612f8f5780825114612e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e64657200000060648201526084016105e6565b6000612e4c8860200151600181518110612ac457612ac46155f9565b90506000815111612edf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c656166290000000000000060648201526084016105e6565b60018d51612eed919061529b565b8914612f7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c65616629000000000000000060648201526084016105e6565b9c506125a49b505050505050505050505050565b60ff85161580612fa2575060ff85166001145b15612fe157612fce8760200151600181518110612fc157612fc16155f9565b60200260200101516138cd565b9950612fda818a6155e1565b9850613069565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e20707265666978000000000000000000000000000060648201526084016105e6565b5050505050506130fc565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f646500000000000000000000000000000000000000000000000060648201526084016105e6565b508061310781615595565b9150506127c1565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e747300000000000000000000000000000000000000000000000000000060648201526084016105e6565b6000808213613203576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e4544000000000000000000000000000000000000000000000060448201526064016105e6565b60006060613210846139fb565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1821361340d57506000919050565b680755bf798b4a1bf1e5821261347f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f57000000000000000000000000000000000000000060448201526064016105e6565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b805160609060008167ffffffffffffffff81111561363b5761363b614b2d565b60405190808252806020026020018201604052801561368057816020015b60408051808201909152606080825260208201528152602001906001900390816136595790505b50905060005b828110156137025760405180604001604052808683815181106136ab576136ab6155f9565b602002602001015181526020016136da8784815181106136cd576136cd6155f9565b6020026020010151613ad1565b8152508282815181106136ef576136ef6155f9565b6020908102919091010152600101613686565b509392505050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613762578060011b82018184015160001a8060041c8253600f811660018301535050600101613734565b509295945050505050565b6060600080600061377d85613ae4565b91945092509050600081600181111561379857613798615731565b14613825576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d0000000000000060648201526084016105e6565b61382f82846155e1565b8551146138be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e64657200000000000000000000000060648201526084016105e6565b61269985602001518484614551565b606060208260000151106138e9576138e48261376d565b61117c565b61117c826145f2565b606061117c6139118360200151600081518110612ac457612ac46155f9565b61370a565b606082518210613935575060408051602081019091526000815261117c565b6125a48383848651613947919061529b565b614608565b60008060008351855110613961578351613964565b84515b90505b80821080156139eb5750838281518110613983576139836155f9565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168583815181106139c2576139c26155f9565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b1561370257816001019150613967565b6000808211613a66576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e4544000000000000000000000000000000000000000000000060448201526064016105e6565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b606061117c613adf836147e0565b6148c9565b600080600080846000015111613ba2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a4016105e6565b6020840151805160001a607f8111613bc757600060016000945094509450505061454a565b60b78111613dd5576000613bdc60808361529b565b905080876000015111613c97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a4016105e6565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613d1057507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613dc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a4016105e6565b506001955093506000925061454a915050565b60bf8111614123576000613dea60b78361529b565b905080876000015111613ea5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a4016105e6565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a4016105e6565b600184015160088302610100031c60378111614047576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a4016105e6565b61405181846155e1565b895111614106576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a4016105e6565b6141118360016155e1565b975095506000945061454a9350505050565b60f7811161420457600061413860c08361529b565b9050808760000151116141f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a4016105e6565b60019550935084925061454a915050565b600061421160f78361529b565b9050808760000151116142cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a4016105e6565b60018301517fff000000000000000000000000000000000000000000000000000000000000001660008190036143aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a4016105e6565b600184015160088302610100031c6037811161446e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a4016105e6565b61447881846155e1565b89511161452d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a4016105e6565b6145388360016155e1565b975095506001945061454a9350505050565b9193909250565b606060008267ffffffffffffffff81111561456e5761456e614b2d565b6040519080825280601f01601f191660200182016040528015614598576020820181803683370190505b509050826000036145aa5790506125a4565b60006145b685876155e1565b90506020820160005b858110156145d75782810151828201526020016145bf565b858111156145e6576000868301525b50919695505050505050565b606061117c826020015160008460000151614551565b60608182601f011015614677576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016105e6565b8282840110156146e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f7700000000000000000000000000000000000060448201526064016105e6565b81830184511015614750576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e647300000000000000000000000000000060448201526064016105e6565b60608215801561476f57604051915060008252602082016040526147d7565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156147a8578051835260209283019201614790565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b604080518082019091526000808252602082015260008251116148ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a4016105e6565b50604080518082019091528151815260209182019181019190915290565b606060008060006148d985613ae4565b9194509250905060018160018111156148f4576148f4615731565b14614981576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d000000000000000060648201526084016105e6565b845161498d83856155e1565b14614a1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e646572000000000000000000000000000060648201526084016105e6565b6040805160208082526104208201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081614a335790505090506000845b8751811015614b2157600080614aa66040518060400160405280858d60000151614a8a919061529b565b8152602001858d60200151614a9f91906155e1565b9052613ae4565b509150915060405180604001604052808383614ac291906155e1565b8152602001848c60200151614ad791906155e1565b815250858581518110614aec57614aec6155f9565b6020908102919091010152614b026001856155e1565b9350614b0e81836155e1565b614b1890846155e1565b92505050614a60565b50815295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614ba357614ba3614b2d565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114614bcf57600080fd5b919050565b600082601f830112614be557600080fd5b813567ffffffffffffffff811115614bff57614bff614b2d565b614c3060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614b5c565b818152846020838601011115614c4557600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614c7457600080fd5b60405160c0810167ffffffffffffffff8282108183111715614c9857614c98614b2d565b8160405282935084358352614caf60208601614bab565b6020840152614cc060408601614bab565b6040840152606085013560608401526080850135608084015260a0850135915080821115614ced57600080fd5b50614cfa85828601614bd4565b60a0830152505092915050565b600080600080600085870360e0811215614d2057600080fd5b863567ffffffffffffffff80821115614d3857600080fd5b614d448a838b01614c62565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614d7d57600080fd5b60408901955060c0890135925080831115614d9757600080fd5b828901925089601f840112614dab57600080fd5b8235915080821115614dbc57600080fd5b508860208260051b8401011115614dd257600080fd5b959894975092955050506020019190565b60005b83811015614dfe578181015183820152602001614de6565b83811115614e0d576000848401525b50505050565b60008151808452614e2b816020860160208601614de3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006125a46020830184614e13565b600060208284031215614e8257600080fd5b5035919050565b80358015158114614bcf57600080fd5b60008060408385031215614eac57600080fd5b614eb583614e89565b9150614ec360208401614bab565b90509250929050565b600060208284031215614ede57600080fd5b813567ffffffffffffffff811115614ef557600080fd5b6122da84828501614c62565b803567ffffffffffffffff81168114614bcf57600080fd5b600060208284031215614f2b57600080fd5b6125a482614f01565b600080600080600060a08688031215614f4c57600080fd5b614f5586614bab565b945060208601359350614f6a60408701614f01565b9250614f7860608701614e89565b9150608086013567ffffffffffffffff811115614f9457600080fd5b614fa088828901614bd4565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251615001816049850160208701614de3565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614bcf57600080fd5b60006060828403121561504457600080fd5b6040516060810181811067ffffffffffffffff8211171561506757615067614b2d565b6040528251815261507a60208401615012565b602082015261508b60408401615012565b60408201529392505050565b6000608082840312156150a957600080fd5b6040516080810181811067ffffffffffffffff821117156150cc576150cc614b2d565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff8084111561511857615118614b2d565b8360051b6020615129818301614b5c565b86815291850191818101903684111561514157600080fd5b865b848110156151755780358681111561515b5760008081fd5b61516736828b01614bd4565b845250918301918301615143565b50979650505050505050565b60008451615193818460208901614de3565b80830190507f2e0000000000000000000000000000000000000000000000000000000000000080825285516151cf816001850160208a01614de3565b600192019182015283516151ea816002840160208801614de3565b0160020195945050505050565b60006020828403121561520957600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff8083168185168183048111821515161561526657615266615210565b02949350505050565b600067ffffffffffffffff80831681851680830382111561529257615292615210565b01949350505050565b6000828210156152ad576152ad615210565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826152f0576152f06152b2565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561534457615344615210565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561538357615383615210565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156153b7576153b7615210565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156153fe576153fe615210565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561543957615439615210565b6000871292508782058712848416161561545557615455615210565b8785058712818416161561546b5761546b615210565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156154b3576154b3615210565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156154e7576154e7615210565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561552557615525615210565b500290565b600082615539576155396152b2565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261558960c0830184614e13565b98975050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036155c6576155c6615210565b5060010190565b6000826155dc576155dc6152b2565b500690565b600082198211156155f4576155f4615210565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b805163ffffffff81168114614bcf57600080fd5b805160ff81168114614bcf57600080fd5b600060c0828403121561565f57600080fd5b60405160c0810181811067ffffffffffffffff8211171561568257615682614b2d565b60405261568e83615628565b815261569c6020840161563c565b60208201526156ad6040840161563c565b60408201526156be60608401615628565b60608201526156cf60808401615628565b60808201526156e060a08401615012565b60a08201529392505050565b600060ff8316806156ff576156ff6152b2565b8060ff84160691505092915050565b600060ff821660ff84168082101561572857615728615210565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a", } // OptimismPortalABI is the input ABI used to generate the binding from. @@ -61,7 +62,7 @@ var OptimismPortalABI = OptimismPortalMetaData.ABI var OptimismPortalBin = OptimismPortalMetaData.Bin // DeployOptimismPortal deploys a new Ethereum contract, binding an instance of OptimismPortal to it. -func DeployOptimismPortal(auth *bind.TransactOpts, backend bind.ContractBackend, _l2Oracle common.Address, _guardian common.Address, _paused bool, _config common.Address) (common.Address, *types.Transaction, *OptimismPortal, error) { +func DeployOptimismPortal(auth *bind.TransactOpts, backend bind.ContractBackend, _l2Oracle common.Address, _guardian common.Address, _config common.Address) (common.Address, *types.Transaction, *OptimismPortal, error) { parsed, err := OptimismPortalMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -70,7 +71,7 @@ func DeployOptimismPortal(auth *bind.TransactOpts, backend bind.ContractBackend, return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(OptimismPortalBin), backend, _l2Oracle, _guardian, _paused, _config) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(OptimismPortalBin), backend, _l2Oracle, _guardian, _config) if err != nil { return common.Address{}, nil, nil, err } @@ -174,11 +175,11 @@ func NewOptimismPortalFilterer(address common.Address, filterer bind.ContractFil // bindOptimismPortal binds a generic wrapper to an already deployed contract. func bindOptimismPortal(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(OptimismPortalABI)) + parsed, err := OptimismPortalMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and @@ -374,6 +375,37 @@ func (_OptimismPortal *OptimismPortalCallerSession) IsOutputFinalized(_l2OutputI return _OptimismPortal.Contract.IsOutputFinalized(&_OptimismPortal.CallOpts, _l2OutputIndex) } +// L1Messenger is a free data retrieval call binding the contract method 0x6140e0e6. +// +// Solidity: function l1Messenger() view returns(address) +func (_OptimismPortal *OptimismPortalCaller) L1Messenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OptimismPortal.contract.Call(opts, &out, "l1Messenger") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// L1Messenger is a free data retrieval call binding the contract method 0x6140e0e6. +// +// Solidity: function l1Messenger() view returns(address) +func (_OptimismPortal *OptimismPortalSession) L1Messenger() (common.Address, error) { + return _OptimismPortal.Contract.L1Messenger(&_OptimismPortal.CallOpts) +} + +// L1Messenger is a free data retrieval call binding the contract method 0x6140e0e6. +// +// Solidity: function l1Messenger() view returns(address) +func (_OptimismPortal *OptimismPortalCallerSession) L1Messenger() (common.Address, error) { + return _OptimismPortal.Contract.L1Messenger(&_OptimismPortal.CallOpts) +} + // L2Sender is a free data retrieval call binding the contract method 0x9bf62d82. // // Solidity: function l2Sender() view returns(address) @@ -661,25 +693,25 @@ func (_OptimismPortal *OptimismPortalTransactorSession) FinalizeWithdrawalTransa return _OptimismPortal.Contract.FinalizeWithdrawalTransaction(&_OptimismPortal.TransactOpts, _tx) } -// Initialize is a paid mutator transaction binding the contract method 0xd53a822f. +// Initialize is a paid mutator transaction binding the contract method 0x85ee7ba6. // -// Solidity: function initialize(bool _paused) returns() -func (_OptimismPortal *OptimismPortalTransactor) Initialize(opts *bind.TransactOpts, _paused bool) (*types.Transaction, error) { - return _OptimismPortal.contract.Transact(opts, "initialize", _paused) +// Solidity: function initialize(bool _paused, address _l1Messenger) returns() +func (_OptimismPortal *OptimismPortalTransactor) Initialize(opts *bind.TransactOpts, _paused bool, _l1Messenger common.Address) (*types.Transaction, error) { + return _OptimismPortal.contract.Transact(opts, "initialize", _paused, _l1Messenger) } -// Initialize is a paid mutator transaction binding the contract method 0xd53a822f. +// Initialize is a paid mutator transaction binding the contract method 0x85ee7ba6. // -// Solidity: function initialize(bool _paused) returns() -func (_OptimismPortal *OptimismPortalSession) Initialize(_paused bool) (*types.Transaction, error) { - return _OptimismPortal.Contract.Initialize(&_OptimismPortal.TransactOpts, _paused) +// Solidity: function initialize(bool _paused, address _l1Messenger) returns() +func (_OptimismPortal *OptimismPortalSession) Initialize(_paused bool, _l1Messenger common.Address) (*types.Transaction, error) { + return _OptimismPortal.Contract.Initialize(&_OptimismPortal.TransactOpts, _paused, _l1Messenger) } -// Initialize is a paid mutator transaction binding the contract method 0xd53a822f. +// Initialize is a paid mutator transaction binding the contract method 0x85ee7ba6. // -// Solidity: function initialize(bool _paused) returns() -func (_OptimismPortal *OptimismPortalTransactorSession) Initialize(_paused bool) (*types.Transaction, error) { - return _OptimismPortal.Contract.Initialize(&_OptimismPortal.TransactOpts, _paused) +// Solidity: function initialize(bool _paused, address _l1Messenger) returns() +func (_OptimismPortal *OptimismPortalTransactorSession) Initialize(_paused bool, _l1Messenger common.Address) (*types.Transaction, error) { + return _OptimismPortal.Contract.Initialize(&_OptimismPortal.TransactOpts, _paused, _l1Messenger) } // Pause is a paid mutator transaction binding the contract method 0x8456cb59. diff --git a/op-bindings/bindings/proxy.go b/op-bindings/bindings/proxy.go index f5979284702f9..2dc21b70d3618 100644 --- a/op-bindings/bindings/proxy.go +++ b/op-bindings/bindings/proxy.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // ProxyMetaData contains all meta data concerning the Proxy contract. @@ -156,11 +157,11 @@ func NewProxyFilterer(address common.Address, filterer bind.ContractFilterer) (* // bindProxy binds a generic wrapper to an already deployed contract. func bindProxy(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ProxyABI)) + parsed, err := ProxyMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/proxyadmin.go b/op-bindings/bindings/proxyadmin.go index 100a6490bd757..51ce13c2d8bc2 100644 --- a/op-bindings/bindings/proxyadmin.go +++ b/op-bindings/bindings/proxyadmin.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // ProxyAdminMetaData contains all meta data concerning the ProxyAdmin contract. @@ -156,11 +157,11 @@ func NewProxyAdminFilterer(address common.Address, filterer bind.ContractFiltere // bindProxyAdmin binds a generic wrapper to an already deployed contract. func bindProxyAdmin(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ProxyAdminABI)) + parsed, err := ProxyAdminMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/sequencerfeevault.go b/op-bindings/bindings/sequencerfeevault.go index a62538e40b088..3b915cdb5f970 100644 --- a/op-bindings/bindings/sequencerfeevault.go +++ b/op-bindings/bindings/sequencerfeevault.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // SequencerFeeVaultMetaData contains all meta data concerning the SequencerFeeVault contract. @@ -156,11 +157,11 @@ func NewSequencerFeeVaultFilterer(address common.Address, filterer bind.Contract // bindSequencerFeeVault binds a generic wrapper to an already deployed contract. func bindSequencerFeeVault(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(SequencerFeeVaultABI)) + parsed, err := SequencerFeeVaultMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/systemconfig.go b/op-bindings/bindings/systemconfig.go index 9598cd419a41a..5f0e280cf128c 100644 --- a/op-bindings/bindings/systemconfig.go +++ b/op-bindings/bindings/systemconfig.go @@ -26,6 +26,7 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // ResourceMeteringResourceConfig is an auto generated low-level Go binding around an user-defined struct. @@ -166,11 +167,11 @@ func NewSystemConfigFilterer(address common.Address, filterer bind.ContractFilte // bindSystemConfig binds a generic wrapper to an already deployed contract. func bindSystemConfig(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(SystemConfigABI)) + parsed, err := SystemConfigMetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-bindings/bindings/weth9.go b/op-bindings/bindings/weth9.go index fc702c27eb20f..e1f45b6d60d10 100644 --- a/op-bindings/bindings/weth9.go +++ b/op-bindings/bindings/weth9.go @@ -26,12 +26,13 @@ var ( _ = common.Big1 _ = types.BloomLookup _ = event.NewSubscription + _ = abi.ConvertType ) // WETH9MetaData contains all meta data concerning the WETH9 contract. var WETH9MetaData = &bind.MetaData{ ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60c0604052600d60808190526c2bb930b83832b21022ba3432b960991b60a090815261002e916000919061007a565b50604080518082019091526004808252630ae8aa8960e31b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b50610115565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100bb57805160ff19168380011785556100e8565b828001600101855582156100e8579182015b828111156100e85782518255916020019190600101906100cd565b506100f49291506100f8565b5090565b61011291905b808211156100f457600081556001016100fe565b90565b6107f9806101246000396000f3fe6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a72315820e496abb80c5983b030f680d0bd88f66bf44e261bc3be070d612dd72f9f1f5e9a64736f6c63430005110032", + Bin: "0x60c0604052600d60808190526c2bb930b83832b21022ba3432b960991b60a090815261002e916000919061007a565b50604080518082019091526004808252630ae8aa8960e31b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b50610115565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100bb57805160ff19168380011785556100e8565b828001600101855582156100e8579182015b828111156100e85782518255916020019190600101906100cd565b506100f49291506100f8565b5090565b61011291905b808211156100f457600081556001016100fe565b90565b6107f9806101246000396000f3fe6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a7231582035630f3bb0dc597462159fde4e472ab40eaf23fad7536c9911cfd181677e702a64736f6c63430005110032", } // WETH9ABI is the input ABI used to generate the binding from. @@ -156,11 +157,11 @@ func NewWETH9Filterer(address common.Address, filterer bind.ContractFilterer) (* // bindWETH9 binds a generic wrapper to an already deployed contract. func bindWETH9(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(WETH9ABI)) + parsed, err := WETH9MetaData.GetAbi() if err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil } // Call invokes the (constant) contract method with params as input values and diff --git a/op-chain-ops/deployer/deployer.go b/op-chain-ops/deployer/deployer.go index 829393df6b95a..3eeb7cca8333a 100644 --- a/op-chain-ops/deployer/deployer.go +++ b/op-chain-ops/deployer/deployer.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "math/big" + "os" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" @@ -95,6 +96,18 @@ func Deploy(backend *backends.SimulatedBackend, constructors []Constructor, cb D return nil, err } + fmt.Println("_______________________________________________________-") + fmt.Println("_______________________________________________________-") + fmt.Println("_______________________________________________________-") + fmt.Println("_______________________________________________________-") + fmt.Println("_______________________________________________________-") + fmt.Println("_______________________________________________________-") + fmt.Println("_______________________________________________________-") + for _, deployment := range constructors { + fmt.Println("name", deployment.Name) + } + os.Exit(0) + opts.GasLimit = 15_000_000 ctx := context.Background() diff --git a/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol b/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol index 21adfed44c16d..5193da4ab604e 100644 --- a/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol +++ b/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol @@ -60,6 +60,8 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { /// This may be removed in the future. bool public paused; + address public l1Messenger; + /// @notice Emitted when a transaction is deposited from L1 to L2. /// The parameters of this event are read by the rollup node and used to derive deposit /// transactions on L2. @@ -103,29 +105,35 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { _; } + /// @notice Pass when onlyMessenger. + modifier onlyMessenger(){ + require(msg.sender == l1Messenger,"messenger contract unauthenticated"); + _; + } + /// @custom:semver 1.7.1 /// @notice Constructs the OptimismPortal contract. /// @param _l2Oracle Address of the L2OutputOracle contract. /// @param _guardian Address that can pause deposits and withdrawals. - /// @param _paused Sets the contract's pausability state. /// @param _config Address of the SystemConfig contract. constructor( L2OutputOracle _l2Oracle, address _guardian, - bool _paused, +// bool _paused, SystemConfig _config ) Semver(1, 7, 1) { L2_ORACLE = _l2Oracle; GUARDIAN = _guardian; SYSTEM_CONFIG = _config; - initialize(_paused); +// initialize(_paused); } /// @notice Initializer. - function initialize(bool _paused) public initializer { + function initialize(bool _paused,address _l1Messenger) public initializer { l2Sender = Constants.DEFAULT_L2_SENDER; paused = _paused; __ResourceMetering_init(); + l1Messenger = _l1Messenger; } /// @notice Pauses deposits and withdrawals. @@ -379,7 +387,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { uint64 _gasLimit, bool _isCreation, bytes memory _data - ) public payable metered(_gasLimit) { + ) public payable metered(_gasLimit) onlyMessenger{ // Just to be safe, make sure that people specify address(0) as the target when doing // contract creations. if (_isCreation) { diff --git a/packages/contracts/L1/deployment/AddressDictator.sol b/packages/contracts/L1/deployment/AddressDictator.sol new file mode 100644 index 0000000000000..1ea95c11c4979 --- /dev/null +++ b/packages/contracts/L1/deployment/AddressDictator.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +import { Lib_AddressManager } from "../../libraries/resolver/Lib_AddressManager.sol"; + +/** + * @title AddressDictator + * @dev The AddressDictator (glory to Arstotzka) is a contract that allows us to safely manipulate + * many different addresses in the AddressManager without transferring ownership of the + * AddressManager to a hot wallet or hardware wallet. + */ +contract AddressDictator { + /********* + * Types * + *********/ + + struct NamedAddress { + string name; + address addr; + } + + /************* + * Variables * + *************/ + + Lib_AddressManager public manager; + address public finalOwner; + NamedAddress[] namedAddresses; + + /*************** + * Constructor * + ***************/ + + /** + * @param _manager Address of the AddressManager contract. + * @param _finalOwner Address to transfer AddressManager ownership to afterwards. + * @param _names Array of names to associate an address with. + * @param _addresses Array of addresses to associate with the name. + */ + constructor( + Lib_AddressManager _manager, + address _finalOwner, + string[] memory _names, + address[] memory _addresses + ) { + manager = _manager; + finalOwner = _finalOwner; + require( + _names.length == _addresses.length, + "AddressDictator: Must provide an equal number of names and addresses." + ); + for (uint256 i = 0; i < _names.length; i++) { + namedAddresses.push(NamedAddress({ name: _names[i], addr: _addresses[i] })); + } + } + + /******************** + * Public Functions * + ********************/ + + /** + * Called to finalize the transfer, this function is callable by anyone, but will only result in + * an upgrade if this contract is the owner Address Manager. + */ + // slither-disable-next-line calls-loop + function setAddresses() external { + for (uint256 i = 0; i < namedAddresses.length; i++) { + manager.setAddress(namedAddresses[i].name, namedAddresses[i].addr); + } + // note that this will revert if _finalOwner == currentOwner + manager.transferOwnership(finalOwner); + } + + /** + * Transfers ownership of this contract to the finalOwner. + * Only callable by the Final Owner, which is intended to be our multisig. + * This function shouldn't be necessary, but it gives a sense of reassurance that we can recover + * if something really surprising goes wrong. + */ + function returnOwnership() external { + require(msg.sender == finalOwner, "AddressDictator: only callable by finalOwner"); + manager.transferOwnership(finalOwner); + } + + /****************** + * View Functions * + ******************/ + + /** + * Returns the full namedAddresses array. + */ + function getNamedAddresses() external view returns (NamedAddress[] memory) { + return namedAddresses; + } +} diff --git a/packages/contracts/L1/deployment/ChugSplashDictator.sol b/packages/contracts/L1/deployment/ChugSplashDictator.sol new file mode 100644 index 0000000000000..0a3e2eba90ca3 --- /dev/null +++ b/packages/contracts/L1/deployment/ChugSplashDictator.sol @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +import { L1ChugSplashProxy } from "../../chugsplash/L1ChugSplashProxy.sol"; +import { iL1ChugSplashDeployer } from "../../chugsplash/interfaces/iL1ChugSplashDeployer.sol"; + +/** + * @title ChugSplashDictator + * @dev Like the AddressDictator, but specifically for the Proxy__OVM_L1StandardBridge. We're + * working on a generalized version of this but this is good enough for the moment. + */ +contract ChugSplashDictator is iL1ChugSplashDeployer { + /************* + * Variables * + *************/ + + // slither-disable-next-line constable-states + bool public isUpgrading = true; + L1ChugSplashProxy public target; + address public finalOwner; + bytes32 public codeHash; + bytes32 public messengerSlotKey; + bytes32 public messengerSlotVal; + bytes32 public bridgeSlotKey; + bytes32 public bridgeSlotVal; + + /*************** + * Constructor * + ***************/ + + constructor( + L1ChugSplashProxy _target, + address _finalOwner, + bytes32 _codeHash, + bytes32 _messengerSlotKey, + bytes32 _messengerSlotVal, + bytes32 _bridgeSlotKey, + bytes32 _bridgeSlotVal + ) { + target = _target; + finalOwner = _finalOwner; + codeHash = _codeHash; + messengerSlotKey = _messengerSlotKey; + messengerSlotVal = _messengerSlotVal; + bridgeSlotKey = _bridgeSlotKey; + bridgeSlotVal = _bridgeSlotVal; + } + + /******************** + * Public Functions * + ********************/ + + function doActions(bytes memory _code) external { + require(keccak256(_code) == codeHash, "ChugSplashDictator: Incorrect code hash."); + + target.setCode(_code); + target.setStorage(messengerSlotKey, messengerSlotVal); + target.setStorage(bridgeSlotKey, bridgeSlotVal); + target.setOwner(finalOwner); + } + + /** + * Transfers ownership of this contract to the finalOwner. + * Only callable by the finalOwner, which is intended to be our multisig. + * This function shouldn't be necessary, but it gives a sense of reassurance that we can + * recover if something really surprising goes wrong. + */ + function returnOwnership() external { + require(msg.sender == finalOwner, "ChugSplashDictator: only callable by finalOwner"); + + target.setOwner(finalOwner); + } +} diff --git a/packages/contracts/L1/messaging/IL1CrossDomainMessenger.sol b/packages/contracts/L1/messaging/IL1CrossDomainMessenger.sol new file mode 100644 index 0000000000000..4fb8026ac6a0d --- /dev/null +++ b/packages/contracts/L1/messaging/IL1CrossDomainMessenger.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Library Imports */ +import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; + +/* Interface Imports */ +import { ICrossDomainMessenger } from "../../libraries/bridge/ICrossDomainMessenger.sol"; + +/** + * @title IL1CrossDomainMessenger + */ +interface IL1CrossDomainMessenger is ICrossDomainMessenger { + /******************* + * Data Structures * + *******************/ + + struct L2MessageInclusionProof { + bytes32 stateRoot; + Lib_OVMCodec.ChainBatchHeader stateRootBatchHeader; + Lib_OVMCodec.ChainInclusionProof stateRootProof; + bytes stateTrieWitness; + bytes storageTrieWitness; + } + + /******************** + * Public Functions * + ********************/ + + /** + * Relays a cross domain message to a contract. + * @param _target Target contract address. + * @param _sender Message sender address. + * @param _message Message to send to the target. + * @param _messageNonce Nonce for the provided message. + * @param _proof Inclusion proof for the given message. + */ + function relayMessage( + address _target, + address _sender, + bytes memory _message, + uint256 _messageNonce, + L2MessageInclusionProof memory _proof + ) external; + + /** + * Replays a cross domain message to the target messenger. + * @param _target Target contract address. + * @param _sender Original sender address. + * @param _message Message to send to the target. + * @param _queueIndex CTC Queue index for the message to replay. + * @param _oldGasLimit Original gas limit used to send the message. + * @param _newGasLimit New gas limit to be used for this message. + */ + function replayMessage( + address _target, + address _sender, + bytes memory _message, + uint256 _queueIndex, + uint32 _oldGasLimit, + uint32 _newGasLimit + ) external; +} diff --git a/packages/contracts/L1/messaging/IL1ERC20Bridge.sol b/packages/contracts/L1/messaging/IL1ERC20Bridge.sol new file mode 100644 index 0000000000000..f8d6680e16867 --- /dev/null +++ b/packages/contracts/L1/messaging/IL1ERC20Bridge.sol @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: MIT +pragma solidity >0.5.0 <0.9.0; + +/** + * @title IL1ERC20Bridge + */ +interface IL1ERC20Bridge { + /********** + * Events * + **********/ + + event ERC20DepositInitiated( + address indexed _l1Token, + address indexed _l2Token, + address indexed _from, + address _to, + uint256 _amount, + bytes _data + ); + + event ERC20WithdrawalFinalized( + address indexed _l1Token, + address indexed _l2Token, + address indexed _from, + address _to, + uint256 _amount, + bytes _data + ); + + /******************** + * Public Functions * + ********************/ + + /** + * @dev get the address of the corresponding L2 bridge contract. + * @return Address of the corresponding L2 bridge contract. + */ + function l2TokenBridge() external returns (address); + + /** + * @dev deposit an amount of the ERC20 to the caller's balance on L2. + * @param _l1Token Address of the L1 ERC20 we are depositing + * @param _l2Token Address of the L1 respective L2 ERC20 + * @param _amount Amount of the ERC20 to deposit + * @param _l2Gas Gas limit required to complete the deposit on L2. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function depositERC20( + address _l1Token, + address _l2Token, + uint256 _amount, + uint32 _l2Gas, + bytes calldata _data + ) external; + + /** + * @dev deposit an amount of ERC20 to a recipient's balance on L2. + * @param _l1Token Address of the L1 ERC20 we are depositing + * @param _l2Token Address of the L1 respective L2 ERC20 + * @param _to L2 address to credit the withdrawal to. + * @param _amount Amount of the ERC20 to deposit. + * @param _l2Gas Gas limit required to complete the deposit on L2. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function depositERC20To( + address _l1Token, + address _l2Token, + address _to, + uint256 _amount, + uint32 _l2Gas, + bytes calldata _data + ) external; + + /************************* + * Cross-chain Functions * + *************************/ + + /** + * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the + * L1 ERC20 token. + * This call will fail if the initialized withdrawal from L2 has not been finalized. + * + * @param _l1Token Address of L1 token to finalizeWithdrawal for. + * @param _l2Token Address of L2 token where withdrawal was initiated. + * @param _from L2 address initiating the transfer. + * @param _to L1 address to credit the withdrawal to. + * @param _amount Amount of the ERC20 to deposit. + * @param _data Data provided by the sender on L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function finalizeERC20Withdrawal( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) external; +} diff --git a/packages/contracts/L1/messaging/IL1StandardBridge.sol b/packages/contracts/L1/messaging/IL1StandardBridge.sol new file mode 100644 index 0000000000000..1478bfe9a308b --- /dev/null +++ b/packages/contracts/L1/messaging/IL1StandardBridge.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: MIT +pragma solidity >0.5.0 <0.9.0; + +import "./IL1ERC20Bridge.sol"; + +/** + * @title IL1StandardBridge + */ +interface IL1StandardBridge is IL1ERC20Bridge { + /********** + * Events * + **********/ + event ETHDepositInitiated( + address indexed _from, + address indexed _to, + uint256 _amount, + bytes _data + ); + + event ETHWithdrawalFinalized( + address indexed _from, + address indexed _to, + uint256 _amount, + bytes _data + ); + + /******************** + * Public Functions * + ********************/ + + /** + * @dev Deposit an amount of the ETH to the caller's balance on L2. + * @param _l2Gas Gas limit required to complete the deposit on L2. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function depositETH(uint32 _l2Gas, bytes calldata _data) external payable; + + /** + * @dev Deposit an amount of ETH to a recipient's balance on L2. + * @param _to L2 address to credit the withdrawal to. + * @param _l2Gas Gas limit required to complete the deposit on L2. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function depositETHTo( + address _to, + uint32 _l2Gas, + bytes calldata _data + ) external payable; + + /************************* + * Cross-chain Functions * + *************************/ + + /** + * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the + * L1 ETH token. Since only the xDomainMessenger can call this function, it will never be called + * before the withdrawal is finalized. + * @param _from L2 address initiating the transfer. + * @param _to L1 address to credit the withdrawal to. + * @param _amount Amount of the ERC20 to deposit. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function finalizeETHWithdrawal( + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) external; +} diff --git a/packages/contracts/L1/messaging/L1CrossDomainMessenger.sol b/packages/contracts/L1/messaging/L1CrossDomainMessenger.sol new file mode 100644 index 0000000000000..8204d2f135ced --- /dev/null +++ b/packages/contracts/L1/messaging/L1CrossDomainMessenger.sol @@ -0,0 +1,377 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Library Imports */ +import { AddressAliasHelper } from "../../standards/AddressAliasHelper.sol"; +import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol"; +import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; +import { Lib_AddressManager } from "../../libraries/resolver/Lib_AddressManager.sol"; +import { Lib_SecureMerkleTrie } from "../../libraries/trie/Lib_SecureMerkleTrie.sol"; +import { Lib_DefaultValues } from "../../libraries/constants/Lib_DefaultValues.sol"; +import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; +import { Lib_CrossDomainUtils } from "../../libraries/bridge/Lib_CrossDomainUtils.sol"; + +/* Interface Imports */ +import { IL1CrossDomainMessenger } from "./IL1CrossDomainMessenger.sol"; +import { ICanonicalTransactionChain } from "../rollup/ICanonicalTransactionChain.sol"; +import { IStateCommitmentChain } from "../rollup/IStateCommitmentChain.sol"; + +/* External Imports */ +import { + OwnableUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import { + PausableUpgradeable +} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; +import { + ReentrancyGuardUpgradeable +} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; + +/** + * @title L1CrossDomainMessenger + * @dev The L1 Cross Domain Messenger contract sends messages from L1 to L2, and relays messages + * from L2 onto L1. In the event that a message sent from L1 to L2 is rejected for exceeding the L2 + * epoch gas limit, it can be resubmitted via this contract's replay function. + * + */ +contract L1CrossDomainMessenger is + IL1CrossDomainMessenger, + Lib_AddressResolver, + OwnableUpgradeable, + PausableUpgradeable, + ReentrancyGuardUpgradeable +{ + /********** + * Events * + **********/ + + event MessageBlocked(bytes32 indexed _xDomainCalldataHash); + + event MessageAllowed(bytes32 indexed _xDomainCalldataHash); + + /********************** + * Contract Variables * + **********************/ + + mapping(bytes32 => bool) public blockedMessages; + mapping(bytes32 => bool) public relayedMessages; + mapping(bytes32 => bool) public successfulMessages; + + address internal xDomainMsgSender = Lib_DefaultValues.DEFAULT_XDOMAIN_SENDER; + + /*************** + * Constructor * + ***************/ + + /** + * This contract is intended to be behind a delegate proxy. + * We pass the zero address to the address resolver just to satisfy the constructor. + * We still need to set this value in initialize(). + */ + constructor() Lib_AddressResolver(address(0)) {} + + /******************** + * Public Functions * + ********************/ + + /** + * @param _libAddressManager Address of the Address Manager. + */ + // slither-disable-next-line external-function + function initialize(address _libAddressManager) public initializer { + require( + address(libAddressManager) == address(0), + "L1CrossDomainMessenger already intialized." + ); + libAddressManager = Lib_AddressManager(_libAddressManager); + xDomainMsgSender = Lib_DefaultValues.DEFAULT_XDOMAIN_SENDER; + + // Initialize upgradable OZ contracts + __Context_init_unchained(); // Context is a dependency for both Ownable and Pausable + __Ownable_init_unchained(); + __Pausable_init_unchained(); + __ReentrancyGuard_init_unchained(); + } + + /** + * Pause relaying. + */ + function pause() external onlyOwner { + _pause(); + } + + /** + * Block a message. + * @param _xDomainCalldataHash Hash of the message to block. + */ + function blockMessage(bytes32 _xDomainCalldataHash) external onlyOwner { + blockedMessages[_xDomainCalldataHash] = true; + emit MessageBlocked(_xDomainCalldataHash); + } + + /** + * Allow a message. + * @param _xDomainCalldataHash Hash of the message to block. + */ + function allowMessage(bytes32 _xDomainCalldataHash) external onlyOwner { + blockedMessages[_xDomainCalldataHash] = false; + emit MessageAllowed(_xDomainCalldataHash); + } + + // slither-disable-next-line external-function + function xDomainMessageSender() public view returns (address) { + require( + xDomainMsgSender != Lib_DefaultValues.DEFAULT_XDOMAIN_SENDER, + "xDomainMessageSender is not set" + ); + return xDomainMsgSender; + } + + /** + * Sends a cross domain message to the target messenger. + * @param _target Target contract address. + * @param _message Message to send to the target. + * @param _gasLimit Gas limit for the provided message. + */ + // slither-disable-next-line external-function + function sendMessage( + address _target, + bytes memory _message, + uint32 _gasLimit + ) public { + address ovmCanonicalTransactionChain = resolve("CanonicalTransactionChain"); + // Use the CTC queue length as nonce + uint40 nonce = ICanonicalTransactionChain(ovmCanonicalTransactionChain).getQueueLength(); + + bytes memory xDomainCalldata = Lib_CrossDomainUtils.encodeXDomainCalldata( + _target, + msg.sender, + _message, + nonce + ); + + // slither-disable-next-line reentrancy-events + _sendXDomainMessage(ovmCanonicalTransactionChain, xDomainCalldata, _gasLimit); + + // slither-disable-next-line reentrancy-events + emit SentMessage(_target, msg.sender, _message, nonce, _gasLimit); + } + + /** + * Relays a cross domain message to a contract. + * @inheritdoc IL1CrossDomainMessenger + */ + // slither-disable-next-line external-function + function relayMessage( + address _target, + address _sender, + bytes memory _message, + uint256 _messageNonce, + L2MessageInclusionProof memory _proof + ) public nonReentrant whenNotPaused { + bytes memory xDomainCalldata = Lib_CrossDomainUtils.encodeXDomainCalldata( + _target, + _sender, + _message, + _messageNonce + ); + + require( + _verifyXDomainMessage(xDomainCalldata, _proof) == true, + "Provided message could not be verified." + ); + + bytes32 xDomainCalldataHash = keccak256(xDomainCalldata); + + require( + successfulMessages[xDomainCalldataHash] == false, + "Provided message has already been received." + ); + + require( + blockedMessages[xDomainCalldataHash] == false, + "Provided message has been blocked." + ); + + require( + _target != resolve("CanonicalTransactionChain"), + "Cannot send L2->L1 messages to L1 system contracts." + ); + + xDomainMsgSender = _sender; + // slither-disable-next-line reentrancy-no-eth, reentrancy-events, reentrancy-benign + (bool success, ) = _target.call(_message); + // slither-disable-next-line reentrancy-benign + xDomainMsgSender = Lib_DefaultValues.DEFAULT_XDOMAIN_SENDER; + + // Mark the message as received if the call was successful. Ensures that a message can be + // relayed multiple times in the case that the call reverted. + if (success == true) { + // slither-disable-next-line reentrancy-no-eth + successfulMessages[xDomainCalldataHash] = true; + // slither-disable-next-line reentrancy-events + emit RelayedMessage(xDomainCalldataHash); + } else { + // slither-disable-next-line reentrancy-events + emit FailedRelayedMessage(xDomainCalldataHash); + } + + // Store an identifier that can be used to prove that the given message was relayed by some + // user. Gives us an easy way to pay relayers for their work. + bytes32 relayId = keccak256(abi.encodePacked(xDomainCalldata, msg.sender, block.number)); + // slither-disable-next-line reentrancy-benign + relayedMessages[relayId] = true; + } + + /** + * Replays a cross domain message to the target messenger. + * @inheritdoc IL1CrossDomainMessenger + */ + // slither-disable-next-line external-function + function replayMessage( + address _target, + address _sender, + bytes memory _message, + uint256 _queueIndex, + uint32 _oldGasLimit, + uint32 _newGasLimit + ) public { + // Verify that the message is in the queue: + address canonicalTransactionChain = resolve("CanonicalTransactionChain"); + Lib_OVMCodec.QueueElement memory element = ICanonicalTransactionChain( + canonicalTransactionChain + ).getQueueElement(_queueIndex); + + // Compute the calldata that was originally used to send the message. + bytes memory xDomainCalldata = Lib_CrossDomainUtils.encodeXDomainCalldata( + _target, + _sender, + _message, + _queueIndex + ); + + // Compute the transactionHash + bytes32 transactionHash = keccak256( + abi.encode( + AddressAliasHelper.applyL1ToL2Alias(address(this)), + Lib_PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER, + _oldGasLimit, + xDomainCalldata + ) + ); + + // Now check that the provided message data matches the one in the queue element. + require( + transactionHash == element.transactionHash, + "Provided message has not been enqueued." + ); + + // Send the same message but with the new gas limit. + _sendXDomainMessage(canonicalTransactionChain, xDomainCalldata, _newGasLimit); + } + + /********************** + * Internal Functions * + **********************/ + + /** + * Verifies that the given message is valid. + * @param _xDomainCalldata Calldata to verify. + * @param _proof Inclusion proof for the message. + * @return Whether or not the provided message is valid. + */ + function _verifyXDomainMessage( + bytes memory _xDomainCalldata, + L2MessageInclusionProof memory _proof + ) internal view returns (bool) { + return (_verifyStateRootProof(_proof) && _verifyStorageProof(_xDomainCalldata, _proof)); + } + + /** + * Verifies that the state root within an inclusion proof is valid. + * @param _proof Message inclusion proof. + * @return Whether or not the provided proof is valid. + */ + function _verifyStateRootProof(L2MessageInclusionProof memory _proof) + internal + view + returns (bool) + { + IStateCommitmentChain ovmStateCommitmentChain = IStateCommitmentChain( + resolve("StateCommitmentChain") + ); + + return (ovmStateCommitmentChain.insideFraudProofWindow(_proof.stateRootBatchHeader) == + false && + ovmStateCommitmentChain.verifyStateCommitment( + _proof.stateRoot, + _proof.stateRootBatchHeader, + _proof.stateRootProof + )); + } + + /** + * Verifies that the storage proof within an inclusion proof is valid. + * @param _xDomainCalldata Encoded message calldata. + * @param _proof Message inclusion proof. + * @return Whether or not the provided proof is valid. + */ + function _verifyStorageProof( + bytes memory _xDomainCalldata, + L2MessageInclusionProof memory _proof + ) internal view returns (bool) { + bytes32 storageKey = keccak256( + abi.encodePacked( + keccak256( + abi.encodePacked( + _xDomainCalldata, + Lib_PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER + ) + ), + uint256(0) + ) + ); + + (bool exists, bytes memory encodedMessagePassingAccount) = Lib_SecureMerkleTrie.get( + abi.encodePacked(Lib_PredeployAddresses.L2_TO_L1_MESSAGE_PASSER), + _proof.stateTrieWitness, + _proof.stateRoot + ); + + require( + exists == true, + "Message passing predeploy has not been initialized or invalid proof provided." + ); + + Lib_OVMCodec.EVMAccount memory account = Lib_OVMCodec.decodeEVMAccount( + encodedMessagePassingAccount + ); + + return + Lib_SecureMerkleTrie.verifyInclusionProof( + abi.encodePacked(storageKey), + abi.encodePacked(uint8(1)), + _proof.storageTrieWitness, + account.storageRoot + ); + } + + /** + * Sends a cross domain message. + * @param _canonicalTransactionChain Address of the CanonicalTransactionChain instance. + * @param _message Message to send. + * @param _gasLimit OVM gas limit for the message. + */ + function _sendXDomainMessage( + address _canonicalTransactionChain, + bytes memory _message, + uint256 _gasLimit + ) internal { + // slither-disable-next-line reentrancy-events + ICanonicalTransactionChain(_canonicalTransactionChain).enqueue( + Lib_PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER, + _gasLimit, + _message + ); + } +} diff --git a/packages/contracts/L1/messaging/L1StandardBridge.sol b/packages/contracts/L1/messaging/L1StandardBridge.sol new file mode 100644 index 0000000000000..3fc7fc0527b97 --- /dev/null +++ b/packages/contracts/L1/messaging/L1StandardBridge.sol @@ -0,0 +1,264 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Interface Imports */ +import { IL1StandardBridge } from "./IL1StandardBridge.sol"; +import { IL1ERC20Bridge } from "./IL1ERC20Bridge.sol"; +import { IL2ERC20Bridge } from "../../L2/messaging/IL2ERC20Bridge.sol"; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +/* Library Imports */ +import { CrossDomainEnabled } from "../../libraries/bridge/CrossDomainEnabled.sol"; +import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; +import { Address } from "@openzeppelin/contracts/utils/Address.sol"; +import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +/** + * @title L1StandardBridge + * @dev The L1 ETH and ERC20 Bridge is a contract which stores deposited L1 funds and standard + * tokens that are in use on L2. It synchronizes a corresponding L2 Bridge, informing it of deposits + * and listening to it for newly finalized withdrawals. + * + */ +contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled { + using SafeERC20 for IERC20; + + /******************************** + * External Contract References * + ********************************/ + + address public l2TokenBridge; + + // Maps L1 token to L2 token to balance of the L1 token deposited + mapping(address => mapping(address => uint256)) public deposits; + + /*************** + * Constructor * + ***************/ + + // This contract lives behind a proxy, so the constructor parameters will go unused. + constructor() CrossDomainEnabled(address(0)) {} + + /****************** + * Initialization * + ******************/ + + /** + * @param _l1messenger L1 Messenger address being used for cross-chain communications. + * @param _l2TokenBridge L2 standard bridge address. + */ + // slither-disable-next-line external-function + function initialize(address _l1messenger, address _l2TokenBridge) public { + require(messenger == address(0), "Contract has already been initialized."); + messenger = _l1messenger; + l2TokenBridge = _l2TokenBridge; + } + + /************** + * Depositing * + **************/ + + /** @dev Modifier requiring sender to be EOA. This check could be bypassed by a malicious + * contract via initcode, but it takes care of the user error we want to avoid. + */ + modifier onlyEOA() { + // Used to stop deposits from contracts (avoid accidentally lost tokens) + require(!Address.isContract(msg.sender), "Account not EOA"); + _; + } + + /** + * @dev This function can be called with no data + * to deposit an amount of ETH to the caller's balance on L2. + * Since the receive function doesn't take data, a conservative + * default amount is forwarded to L2. + */ + receive() external payable onlyEOA { + _initiateETHDeposit(msg.sender, msg.sender, 200_000, bytes("")); + } + + /** + * @inheritdoc IL1StandardBridge + */ + function depositETH(uint32 _l2Gas, bytes calldata _data) external payable onlyEOA { + _initiateETHDeposit(msg.sender, msg.sender, _l2Gas, _data); + } + + /** + * @inheritdoc IL1StandardBridge + */ + function depositETHTo( + address _to, + uint32 _l2Gas, + bytes calldata _data + ) external payable { + _initiateETHDeposit(msg.sender, _to, _l2Gas, _data); + } + + /** + * @dev Performs the logic for deposits by storing the ETH and informing the L2 ETH Gateway of + * the deposit. + * @param _from Account to pull the deposit from on L1. + * @param _to Account to give the deposit to on L2. + * @param _l2Gas Gas limit required to complete the deposit on L2. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function _initiateETHDeposit( + address _from, + address _to, + uint32 _l2Gas, + bytes memory _data + ) internal { + // Construct calldata for finalizeDeposit call + bytes memory message = abi.encodeWithSelector( + IL2ERC20Bridge.finalizeDeposit.selector, + address(0), + Lib_PredeployAddresses.OVM_ETH, + _from, + _to, + msg.value, + _data + ); + + // Send calldata into L2 + // slither-disable-next-line reentrancy-events + sendCrossDomainMessage(l2TokenBridge, _l2Gas, message); + + // slither-disable-next-line reentrancy-events + emit ETHDepositInitiated(_from, _to, msg.value, _data); + } + + /** + * @inheritdoc IL1ERC20Bridge + */ + function depositERC20( + address _l1Token, + address _l2Token, + uint256 _amount, + uint32 _l2Gas, + bytes calldata _data + ) external virtual onlyEOA { + _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, msg.sender, _amount, _l2Gas, _data); + } + + /** + * @inheritdoc IL1ERC20Bridge + */ + function depositERC20To( + address _l1Token, + address _l2Token, + address _to, + uint256 _amount, + uint32 _l2Gas, + bytes calldata _data + ) external virtual { + _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, _to, _amount, _l2Gas, _data); + } + + /** + * @dev Performs the logic for deposits by informing the L2 Deposited Token + * contract of the deposit and calling a handler to lock the L1 funds. (e.g. transferFrom) + * + * @param _l1Token Address of the L1 ERC20 we are depositing + * @param _l2Token Address of the L1 respective L2 ERC20 + * @param _from Account to pull the deposit from on L1 + * @param _to Account to give the deposit to on L2 + * @param _amount Amount of the ERC20 to deposit. + * @param _l2Gas Gas limit required to complete the deposit on L2. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function _initiateERC20Deposit( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + uint32 _l2Gas, + bytes calldata _data + ) internal { + // When a deposit is initiated on L1, the L1 Bridge transfers the funds to itself for future + // withdrawals. The use of safeTransferFrom enables support of "broken tokens" which do not + // return a boolean value. + // slither-disable-next-line reentrancy-events, reentrancy-benign + IERC20(_l1Token).safeTransferFrom(_from, address(this), _amount); + + // Construct calldata for _l2Token.finalizeDeposit(_to, _amount) + bytes memory message = abi.encodeWithSelector( + IL2ERC20Bridge.finalizeDeposit.selector, + _l1Token, + _l2Token, + _from, + _to, + _amount, + _data + ); + + // Send calldata into L2 + // slither-disable-next-line reentrancy-events, reentrancy-benign + sendCrossDomainMessage(l2TokenBridge, _l2Gas, message); + + // slither-disable-next-line reentrancy-benign + deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token] + _amount; + + // slither-disable-next-line reentrancy-events + emit ERC20DepositInitiated(_l1Token, _l2Token, _from, _to, _amount, _data); + } + + /************************* + * Cross-chain Functions * + *************************/ + + /** + * @inheritdoc IL1StandardBridge + */ + function finalizeETHWithdrawal( + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) external onlyFromCrossDomainAccount(l2TokenBridge) { + // slither-disable-next-line reentrancy-events + (bool success, ) = _to.call{ value: _amount }(new bytes(0)); + require(success, "TransferHelper::safeTransferETH: ETH transfer failed"); + + // slither-disable-next-line reentrancy-events + emit ETHWithdrawalFinalized(_from, _to, _amount, _data); + } + + /** + * @inheritdoc IL1ERC20Bridge + */ + function finalizeERC20Withdrawal( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) external onlyFromCrossDomainAccount(l2TokenBridge) { + deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token] - _amount; + + // When a withdrawal is finalized on L1, the L1 Bridge transfers the funds to the withdrawer + // slither-disable-next-line reentrancy-events + IERC20(_l1Token).safeTransfer(_to, _amount); + + // slither-disable-next-line reentrancy-events + emit ERC20WithdrawalFinalized(_l1Token, _l2Token, _from, _to, _amount, _data); + } + + /***************************** + * Temporary - Migrating ETH * + *****************************/ + + /** + * @dev Adds ETH balance to the account. This is meant to allow for ETH + * to be migrated from an old gateway to a new gateway. + * NOTE: This is left for one upgrade only so we are able to receive the migrated ETH from the + * old contract + */ + function donateETH() external payable {} +} diff --git a/packages/contracts/L1/rollup/CanonicalTransactionChain.sol b/packages/contracts/L1/rollup/CanonicalTransactionChain.sol new file mode 100644 index 0000000000000..6a131e361dbdb --- /dev/null +++ b/packages/contracts/L1/rollup/CanonicalTransactionChain.sol @@ -0,0 +1,537 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Library Imports */ +import { AddressAliasHelper } from "../../standards/AddressAliasHelper.sol"; +import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; +import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol"; + +/* Interface Imports */ +import { ICanonicalTransactionChain } from "./ICanonicalTransactionChain.sol"; +import { IChainStorageContainer } from "./IChainStorageContainer.sol"; + +/** + * @title CanonicalTransactionChain + * @dev The Canonical Transaction Chain (CTC) contract is an append-only log of transactions + * which must be applied to the rollup state. It defines the ordering of rollup transactions by + * writing them to the 'CTC:batches' instance of the Chain Storage Container. + * The CTC also allows any account to 'enqueue' an L2 transaction, which will require that the + * Sequencer will eventually append it to the rollup state. + * + */ +contract CanonicalTransactionChain is ICanonicalTransactionChain, Lib_AddressResolver { + /************* + * Constants * + *************/ + + // L2 tx gas-related + uint256 public constant MIN_ROLLUP_TX_GAS = 100000; + uint256 public constant MAX_ROLLUP_TX_SIZE = 50000; + + // The approximate cost of calling the enqueue function + uint256 public enqueueGasCost; + // The ratio of the cost of L1 gas to the cost of L2 gas + uint256 public l2GasDiscountDivisor; + // The amount of L2 gas which can be forwarded to L2 without spam prevention via 'gas burn'. + // Calculated as the product of l2GasDiscountDivisor * enqueueGasCost. + // See comments in enqueue() for further detail. + uint256 public enqueueL2GasPrepaid; + + // Encoding-related (all in bytes) + uint256 internal constant BATCH_CONTEXT_SIZE = 16; + // slither-disable-next-line unused-state + uint256 internal constant BATCH_CONTEXT_LENGTH_POS = 12; + uint256 internal constant BATCH_CONTEXT_START_POS = 15; + // slither-disable-next-line unused-state + uint256 internal constant TX_DATA_HEADER_SIZE = 3; + // slither-disable-next-line unused-state + uint256 internal constant BYTES_TILL_TX_DATA = 65; + + /************* + * Variables * + *************/ + + uint256 public maxTransactionGasLimit; + + /*************** + * Queue State * + ***************/ + + uint40 private _nextQueueIndex; // index of the first queue element not yet included + Lib_OVMCodec.QueueElement[] queueElements; + + /*************** + * Constructor * + ***************/ + + constructor( + address _libAddressManager, + uint256 _maxTransactionGasLimit, + uint256 _l2GasDiscountDivisor, + uint256 _enqueueGasCost + ) Lib_AddressResolver(_libAddressManager) { + maxTransactionGasLimit = _maxTransactionGasLimit; + l2GasDiscountDivisor = _l2GasDiscountDivisor; + enqueueGasCost = _enqueueGasCost; + enqueueL2GasPrepaid = _l2GasDiscountDivisor * _enqueueGasCost; + } + + /********************** + * Function Modifiers * + **********************/ + + /** + * Modifier to enforce that, if configured, only the Burn Admin may + * successfully call a method. + */ + modifier onlyBurnAdmin() { + require(msg.sender == libAddressManager.owner(), "Only callable by the Burn Admin."); + _; + } + + /******************************* + * Authorized Setter Functions * + *******************************/ + + /** + * Allows the Burn Admin to update the parameters which determine the amount of gas to burn. + * The value of enqueueL2GasPrepaid is immediately updated as well. + * @param _l2GasDiscountDivisor The ratio of the cost of L1 gas to the cost of L2 gas + * @param _enqueueGasCost The approximate cost of calling the enqueue function + */ + function setGasParams(uint256 _l2GasDiscountDivisor, uint256 _enqueueGasCost) + external + onlyBurnAdmin + { + enqueueGasCost = _enqueueGasCost; + l2GasDiscountDivisor = _l2GasDiscountDivisor; + // See the comment in enqueue() for the rationale behind this formula. + enqueueL2GasPrepaid = _l2GasDiscountDivisor * _enqueueGasCost; + + emit L2GasParamsUpdated(l2GasDiscountDivisor, enqueueGasCost, enqueueL2GasPrepaid); + } + + /******************** + * Public Functions * + ********************/ + + /** + * Accesses the batch storage container. + * @return Reference to the batch storage container. + */ + function batches() public view returns (IChainStorageContainer) { + return IChainStorageContainer(resolve("ChainStorageContainer-CTC-batches")); + } + + /** + * Retrieves the total number of elements submitted. + * @return _totalElements Total submitted elements. + */ + function getTotalElements() public view returns (uint256 _totalElements) { + (uint40 totalElements, , , ) = _getBatchExtraData(); + return uint256(totalElements); + } + + /** + * Retrieves the total number of batches submitted. + * @return _totalBatches Total submitted batches. + */ + // slither-disable-next-line external-function + function getTotalBatches() public view returns (uint256 _totalBatches) { + return batches().length(); + } + + /** + * Returns the index of the next element to be enqueued. + * @return Index for the next queue element. + */ + // slither-disable-next-line external-function + function getNextQueueIndex() public view returns (uint40) { + return _nextQueueIndex; + } + + /** + * Returns the timestamp of the last transaction. + * @return Timestamp for the last transaction. + */ + // slither-disable-next-line external-function + function getLastTimestamp() public view returns (uint40) { + (, , uint40 lastTimestamp, ) = _getBatchExtraData(); + return lastTimestamp; + } + + /** + * Returns the blocknumber of the last transaction. + * @return Blocknumber for the last transaction. + */ + // slither-disable-next-line external-function + function getLastBlockNumber() public view returns (uint40) { + (, , , uint40 lastBlockNumber) = _getBatchExtraData(); + return lastBlockNumber; + } + + /** + * Gets the queue element at a particular index. + * @param _index Index of the queue element to access. + * @return _element Queue element at the given index. + */ + // slither-disable-next-line external-function + function getQueueElement(uint256 _index) + public + view + returns (Lib_OVMCodec.QueueElement memory _element) + { + return queueElements[_index]; + } + + /** + * Get the number of queue elements which have not yet been included. + * @return Number of pending queue elements. + */ + // slither-disable-next-line external-function + function getNumPendingQueueElements() public view returns (uint40) { + return uint40(queueElements.length) - _nextQueueIndex; + } + + /** + * Retrieves the length of the queue, including + * both pending and canonical transactions. + * @return Length of the queue. + */ + // slither-disable-next-line external-function + function getQueueLength() public view returns (uint40) { + return uint40(queueElements.length); + } + + /** + * Adds a transaction to the queue. + * @param _target Target L2 contract to send the transaction to. + * @param _gasLimit Gas limit for the enqueued L2 transaction. + * @param _data Transaction data. + */ + function enqueue( + address _target, + uint256 _gasLimit, + bytes memory _data + ) external { + require( + _data.length <= MAX_ROLLUP_TX_SIZE, + "Transaction data size exceeds maximum for rollup transaction." + ); + + require( + _gasLimit <= maxTransactionGasLimit, + "Transaction gas limit exceeds maximum for rollup transaction." + ); + + require(_gasLimit >= MIN_ROLLUP_TX_GAS, "Transaction gas limit too low to enqueue."); + + // Transactions submitted to the queue lack a method for paying gas fees to the Sequencer. + // So we need to prevent spam attacks by ensuring that the cost of enqueueing a transaction + // from L1 to L2 is not underpriced. For transaction with a high L2 gas limit, we do this by + // burning some extra gas on L1. Of course there is also some intrinsic cost to enqueueing a + // transaction, so we want to make sure not to over-charge (by burning too much L1 gas). + // Therefore, we define 'enqueueL2GasPrepaid' as the L2 gas limit above which we must burn + // additional gas on L1. This threshold is the product of two inputs: + // 1. enqueueGasCost: the base cost of calling this function. + // 2. l2GasDiscountDivisor: the ratio between the cost of gas on L1 and L2. This is a + // positive integer, meaning we assume L2 gas is always less costly. + // The calculation below for gasToConsume can be seen as converting the difference (between + // the specified L2 gas limit and the prepaid L2 gas limit) to an L1 gas amount. + if (_gasLimit > enqueueL2GasPrepaid) { + uint256 gasToConsume = (_gasLimit - enqueueL2GasPrepaid) / l2GasDiscountDivisor; + uint256 startingGas = gasleft(); + + // Although this check is not necessary (burn below will run out of gas if not true), it + // gives the user an explicit reason as to why the enqueue attempt failed. + require(startingGas > gasToConsume, "Insufficient gas for L2 rate limiting burn."); + + uint256 i; + while (startingGas - gasleft() < gasToConsume) { + i++; + } + } + + // Apply an aliasing unless msg.sender == tx.origin. This prevents an attack in which a + // contract on L1 has the same address as a contract on L2 but doesn't have the same code. + // We can safely ignore this for EOAs because they're guaranteed to have the same "code" + // (i.e. no code at all). This also makes it possible for users to interact with contracts + // on L2 even when the Sequencer is down. + address sender; + if (msg.sender == tx.origin) { + sender = msg.sender; + } else { + sender = AddressAliasHelper.applyL1ToL2Alias(msg.sender); + } + + bytes32 transactionHash = keccak256(abi.encode(sender, _target, _gasLimit, _data)); + + queueElements.push( + Lib_OVMCodec.QueueElement({ + transactionHash: transactionHash, + timestamp: uint40(block.timestamp), + blockNumber: uint40(block.number) + }) + ); + uint256 queueIndex = queueElements.length - 1; + emit TransactionEnqueued(sender, _target, _gasLimit, _data, queueIndex, block.timestamp); + } + + /** + * Allows the sequencer to append a batch of transactions. + * @dev This function uses a custom encoding scheme for efficiency reasons. + * .param _shouldStartAtElement Specific batch we expect to start appending to. + * .param _totalElementsToAppend Total number of batch elements we expect to append. + * .param _contexts Array of batch contexts. + * .param _transactionDataFields Array of raw transaction data. + */ + function appendSequencerBatch() external { + uint40 shouldStartAtElement; + uint24 totalElementsToAppend; + uint24 numContexts; + assembly { + shouldStartAtElement := shr(216, calldataload(4)) + totalElementsToAppend := shr(232, calldataload(9)) + numContexts := shr(232, calldataload(12)) + } + + require( + shouldStartAtElement == getTotalElements(), + "Actual batch start index does not match expected start index." + ); + + require( + msg.sender == resolve("OVM_Sequencer"), + "Function can only be called by the Sequencer." + ); + + uint40 nextTransactionPtr = uint40( + BATCH_CONTEXT_START_POS + BATCH_CONTEXT_SIZE * numContexts + ); + + require(msg.data.length >= nextTransactionPtr, "Not enough BatchContexts provided."); + + // Counter for number of sequencer transactions appended so far. + uint32 numSequencerTransactions = 0; + + // Cache the _nextQueueIndex storage variable to a temporary stack variable. + // This is safe as long as nothing reads or writes to the storage variable + // until it is updated by the temp variable. + uint40 nextQueueIndex = _nextQueueIndex; + + BatchContext memory curContext; + for (uint32 i = 0; i < numContexts; i++) { + BatchContext memory nextContext = _getBatchContext(i); + + // Now we can update our current context. + curContext = nextContext; + + // Process sequencer transactions first. + numSequencerTransactions += uint32(curContext.numSequencedTransactions); + + // Now process any subsequent queue transactions. + nextQueueIndex += uint40(curContext.numSubsequentQueueTransactions); + } + + require( + nextQueueIndex <= queueElements.length, + "Attempted to append more elements than are available in the queue." + ); + + // Generate the required metadata that we need to append this batch + uint40 numQueuedTransactions = totalElementsToAppend - numSequencerTransactions; + uint40 blockTimestamp; + uint40 blockNumber; + if (curContext.numSubsequentQueueTransactions == 0) { + // The last element is a sequencer tx, therefore pull timestamp and block number from + // the last context. + blockTimestamp = uint40(curContext.timestamp); + blockNumber = uint40(curContext.blockNumber); + } else { + // The last element is a queue tx, therefore pull timestamp and block number from the + // queue element. + // curContext.numSubsequentQueueTransactions > 0 which means that we've processed at + // least one queue element. We increment nextQueueIndex after processing each queue + // element, so the index of the last element we processed is nextQueueIndex - 1. + Lib_OVMCodec.QueueElement memory lastElement = queueElements[nextQueueIndex - 1]; + + blockTimestamp = lastElement.timestamp; + blockNumber = lastElement.blockNumber; + } + + // Cache the previous blockhash to ensure all transaction data can be retrieved efficiently. + // slither-disable-next-line reentrancy-no-eth, reentrancy-events + _appendBatch( + blockhash(block.number - 1), + totalElementsToAppend, + numQueuedTransactions, + blockTimestamp, + blockNumber + ); + + // slither-disable-next-line reentrancy-events + emit SequencerBatchAppended( + nextQueueIndex - numQueuedTransactions, + numQueuedTransactions, + getTotalElements() + ); + + // Update the _nextQueueIndex storage variable. + // slither-disable-next-line reentrancy-no-eth + _nextQueueIndex = nextQueueIndex; + } + + /********************** + * Internal Functions * + **********************/ + + /** + * Returns the BatchContext located at a particular index. + * @param _index The index of the BatchContext + * @return The BatchContext at the specified index. + */ + function _getBatchContext(uint256 _index) internal pure returns (BatchContext memory) { + uint256 contextPtr = 15 + _index * BATCH_CONTEXT_SIZE; + // slither-disable-next-line similar-names + uint256 numSequencedTransactions; + uint256 numSubsequentQueueTransactions; + uint256 ctxTimestamp; + uint256 ctxBlockNumber; + + assembly { + numSequencedTransactions := shr(232, calldataload(contextPtr)) + numSubsequentQueueTransactions := shr(232, calldataload(add(contextPtr, 3))) + ctxTimestamp := shr(216, calldataload(add(contextPtr, 6))) + ctxBlockNumber := shr(216, calldataload(add(contextPtr, 11))) + } + + return + BatchContext({ + numSequencedTransactions: numSequencedTransactions, + numSubsequentQueueTransactions: numSubsequentQueueTransactions, + timestamp: ctxTimestamp, + blockNumber: ctxBlockNumber + }); + } + + /** + * Parses the batch context from the extra data. + * @return Total number of elements submitted. + * @return Index of the next queue element. + * @return Timestamp for the last transaction + * @return Block number for the last transaction. + */ + function _getBatchExtraData() + internal + view + returns ( + uint40, + uint40, + uint40, + uint40 + ) + { + bytes27 extraData = batches().getGlobalMetadata(); + + uint40 totalElements; + uint40 nextQueueIndex; + uint40 lastTimestamp; + uint40 lastBlockNumber; + + // solhint-disable max-line-length + assembly { + extraData := shr(40, extraData) + totalElements := and( + extraData, + 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF + ) + nextQueueIndex := shr( + 40, + and(extraData, 0x00000000000000000000000000000000000000000000FFFFFFFFFF0000000000) + ) + lastTimestamp := shr( + 80, + and(extraData, 0x0000000000000000000000000000000000FFFFFFFFFF00000000000000000000) + ) + lastBlockNumber := shr( + 120, + and(extraData, 0x000000000000000000000000FFFFFFFFFF000000000000000000000000000000) + ) + } + // solhint-enable max-line-length + + return (totalElements, nextQueueIndex, lastTimestamp, lastBlockNumber); + } + + /** + * Encodes the batch context for the extra data. + * @param _totalElements Total number of elements submitted. + * @param _nextQueueIdx Index of the next queue element. + * @param _timestamp Timestamp for the last batch. + * @param _blockNumber Block number of the last batch. + * @return Encoded batch context. + */ + function _makeBatchExtraData( + uint40 _totalElements, + uint40 _nextQueueIdx, + uint40 _timestamp, + uint40 _blockNumber + ) internal pure returns (bytes27) { + bytes27 extraData; + assembly { + extraData := _totalElements + extraData := or(extraData, shl(40, _nextQueueIdx)) + extraData := or(extraData, shl(80, _timestamp)) + extraData := or(extraData, shl(120, _blockNumber)) + extraData := shl(40, extraData) + } + + return extraData; + } + + /** + * Inserts a batch into the chain of batches. + * @param _transactionRoot Root of the transaction tree for this batch. + * @param _batchSize Number of elements in the batch. + * @param _numQueuedTransactions Number of queue transactions in the batch. + * @param _timestamp The latest batch timestamp. + * @param _blockNumber The latest batch blockNumber. + */ + function _appendBatch( + bytes32 _transactionRoot, + uint256 _batchSize, + uint256 _numQueuedTransactions, + uint40 _timestamp, + uint40 _blockNumber + ) internal { + IChainStorageContainer batchesRef = batches(); + (uint40 totalElements, uint40 nextQueueIndex, , ) = _getBatchExtraData(); + + Lib_OVMCodec.ChainBatchHeader memory header = Lib_OVMCodec.ChainBatchHeader({ + batchIndex: batchesRef.length(), + batchRoot: _transactionRoot, + batchSize: _batchSize, + prevTotalElements: totalElements, + extraData: hex"" + }); + + emit TransactionBatchAppended( + header.batchIndex, + header.batchRoot, + header.batchSize, + header.prevTotalElements, + header.extraData + ); + + bytes32 batchHeaderHash = Lib_OVMCodec.hashBatchHeader(header); + bytes27 latestBatchContext = _makeBatchExtraData( + totalElements + uint40(header.batchSize), + nextQueueIndex + uint40(_numQueuedTransactions), + _timestamp, + _blockNumber + ); + + // slither-disable-next-line reentrancy-no-eth, reentrancy-events + batchesRef.push(batchHeaderHash, latestBatchContext); + } +} diff --git a/packages/contracts/L1/rollup/ChainStorageContainer.sol b/packages/contracts/L1/rollup/ChainStorageContainer.sol new file mode 100644 index 0000000000000..2922ae06f665b --- /dev/null +++ b/packages/contracts/L1/rollup/ChainStorageContainer.sol @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Library Imports */ +import { Lib_Buffer } from "../../libraries/utils/Lib_Buffer.sol"; +import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol"; + +/* Interface Imports */ +import { IChainStorageContainer } from "./IChainStorageContainer.sol"; + +/** + * @title ChainStorageContainer + * @dev The Chain Storage Container provides its owner contract with read, write and delete + * functionality. This provides gas efficiency gains by enabling it to overwrite storage slots which + * can no longer be used in a fraud proof due to the fraud window having passed, and the associated + * chain state or transactions being finalized. + * Three distinct Chain Storage Containers will be deployed on Layer 1: + * 1. Stores transaction batches for the Canonical Transaction Chain + * 2. Stores queued transactions for the Canonical Transaction Chain + * 3. Stores chain state batches for the State Commitment Chain + * + */ +contract ChainStorageContainer is IChainStorageContainer, Lib_AddressResolver { + /************* + * Libraries * + *************/ + + using Lib_Buffer for Lib_Buffer.Buffer; + + /************* + * Variables * + *************/ + + string public owner; + Lib_Buffer.Buffer internal buffer; + + /*************** + * Constructor * + ***************/ + + /** + * @param _libAddressManager Address of the Address Manager. + * @param _owner Name of the contract that owns this container (will be resolved later). + */ + constructor(address _libAddressManager, string memory _owner) + Lib_AddressResolver(_libAddressManager) + { + owner = _owner; + } + + /********************** + * Function Modifiers * + **********************/ + + modifier onlyOwner() { + require( + msg.sender == resolve(owner), + "ChainStorageContainer: Function can only be called by the owner." + ); + _; + } + + /******************** + * Public Functions * + ********************/ + + /** + * @inheritdoc IChainStorageContainer + */ + // slither-disable-next-line external-function + function setGlobalMetadata(bytes27 _globalMetadata) public onlyOwner { + return buffer.setExtraData(_globalMetadata); + } + + /** + * @inheritdoc IChainStorageContainer + */ + // slither-disable-next-line external-function + function getGlobalMetadata() public view returns (bytes27) { + return buffer.getExtraData(); + } + + /** + * @inheritdoc IChainStorageContainer + */ + // slither-disable-next-line external-function + function length() public view returns (uint256) { + return uint256(buffer.getLength()); + } + + /** + * @inheritdoc IChainStorageContainer + */ + // slither-disable-next-line external-function + function push(bytes32 _object) public onlyOwner { + buffer.push(_object); + } + + /** + * @inheritdoc IChainStorageContainer + */ + // slither-disable-next-line external-function + function push(bytes32 _object, bytes27 _globalMetadata) public onlyOwner { + buffer.push(_object, _globalMetadata); + } + + /** + * @inheritdoc IChainStorageContainer + */ + // slither-disable-next-line external-function + function get(uint256 _index) public view returns (bytes32) { + return buffer.get(uint40(_index)); + } + + /** + * @inheritdoc IChainStorageContainer + */ + // slither-disable-next-line external-function + function deleteElementsAfterInclusive(uint256 _index) public onlyOwner { + buffer.deleteElementsAfterInclusive(uint40(_index)); + } + + /** + * @inheritdoc IChainStorageContainer + */ + // slither-disable-next-line external-function + function deleteElementsAfterInclusive(uint256 _index, bytes27 _globalMetadata) + public + onlyOwner + { + buffer.deleteElementsAfterInclusive(uint40(_index), _globalMetadata); + } +} diff --git a/packages/contracts/L1/rollup/ICanonicalTransactionChain.sol b/packages/contracts/L1/rollup/ICanonicalTransactionChain.sol new file mode 100644 index 0000000000000..36f4cba4c5dd8 --- /dev/null +++ b/packages/contracts/L1/rollup/ICanonicalTransactionChain.sol @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: MIT +pragma solidity >0.5.0 <0.9.0; + +/* Library Imports */ +import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; + +/* Interface Imports */ +import { IChainStorageContainer } from "./IChainStorageContainer.sol"; + +/** + * @title ICanonicalTransactionChain + */ +interface ICanonicalTransactionChain { + /********** + * Events * + **********/ + + event L2GasParamsUpdated( + uint256 l2GasDiscountDivisor, + uint256 enqueueGasCost, + uint256 enqueueL2GasPrepaid + ); + + event TransactionEnqueued( + address indexed _l1TxOrigin, + address indexed _target, + uint256 _gasLimit, + bytes _data, + uint256 indexed _queueIndex, + uint256 _timestamp + ); + + event QueueBatchAppended( + uint256 _startingQueueIndex, + uint256 _numQueueElements, + uint256 _totalElements + ); + + event SequencerBatchAppended( + uint256 _startingQueueIndex, + uint256 _numQueueElements, + uint256 _totalElements + ); + + event TransactionBatchAppended( + uint256 indexed _batchIndex, + bytes32 _batchRoot, + uint256 _batchSize, + uint256 _prevTotalElements, + bytes _extraData + ); + + /*********** + * Structs * + ***********/ + + struct BatchContext { + uint256 numSequencedTransactions; + uint256 numSubsequentQueueTransactions; + uint256 timestamp; + uint256 blockNumber; + } + + /******************************* + * Authorized Setter Functions * + *******************************/ + + /** + * Allows the Burn Admin to update the parameters which determine the amount of gas to burn. + * The value of enqueueL2GasPrepaid is immediately updated as well. + */ + function setGasParams(uint256 _l2GasDiscountDivisor, uint256 _enqueueGasCost) external; + + /******************** + * Public Functions * + ********************/ + + /** + * Accesses the batch storage container. + * @return Reference to the batch storage container. + */ + function batches() external view returns (IChainStorageContainer); + + /** + * Retrieves the total number of elements submitted. + * @return _totalElements Total submitted elements. + */ + function getTotalElements() external view returns (uint256 _totalElements); + + /** + * Retrieves the total number of batches submitted. + * @return _totalBatches Total submitted batches. + */ + function getTotalBatches() external view returns (uint256 _totalBatches); + + /** + * Returns the index of the next element to be enqueued. + * @return Index for the next queue element. + */ + function getNextQueueIndex() external view returns (uint40); + + /** + * Gets the queue element at a particular index. + * @param _index Index of the queue element to access. + * @return _element Queue element at the given index. + */ + function getQueueElement(uint256 _index) + external + view + returns (Lib_OVMCodec.QueueElement memory _element); + + /** + * Returns the timestamp of the last transaction. + * @return Timestamp for the last transaction. + */ + function getLastTimestamp() external view returns (uint40); + + /** + * Returns the blocknumber of the last transaction. + * @return Blocknumber for the last transaction. + */ + function getLastBlockNumber() external view returns (uint40); + + /** + * Get the number of queue elements which have not yet been included. + * @return Number of pending queue elements. + */ + function getNumPendingQueueElements() external view returns (uint40); + + /** + * Retrieves the length of the queue, including + * both pending and canonical transactions. + * @return Length of the queue. + */ + function getQueueLength() external view returns (uint40); + + /** + * Adds a transaction to the queue. + * @param _target Target contract to send the transaction to. + * @param _gasLimit Gas limit for the given transaction. + * @param _data Transaction data. + */ + function enqueue( + address _target, + uint256 _gasLimit, + bytes memory _data + ) external; + + /** + * Allows the sequencer to append a batch of transactions. + * @dev This function uses a custom encoding scheme for efficiency reasons. + * .param _shouldStartAtElement Specific batch we expect to start appending to. + * .param _totalElementsToAppend Total number of batch elements we expect to append. + * .param _contexts Array of batch contexts. + * .param _transactionDataFields Array of raw transaction data. + */ + function appendSequencerBatch( + // uint40 _shouldStartAtElement, + // uint24 _totalElementsToAppend, + // BatchContext[] _contexts, + // bytes[] _transactionDataFields + ) external; +} diff --git a/packages/contracts/L1/rollup/IChainStorageContainer.sol b/packages/contracts/L1/rollup/IChainStorageContainer.sol new file mode 100644 index 0000000000000..413af507f1aa6 --- /dev/null +++ b/packages/contracts/L1/rollup/IChainStorageContainer.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT +pragma solidity >0.5.0 <0.9.0; + +/** + * @title IChainStorageContainer + */ +interface IChainStorageContainer { + /******************** + * Public Functions * + ********************/ + + /** + * Sets the container's global metadata field. We're using `bytes27` here because we use five + * bytes to maintain the length of the underlying data structure, meaning we have an extra + * 27 bytes to store arbitrary data. + * @param _globalMetadata New global metadata to set. + */ + function setGlobalMetadata(bytes27 _globalMetadata) external; + + /** + * Retrieves the container's global metadata field. + * @return Container global metadata field. + */ + function getGlobalMetadata() external view returns (bytes27); + + /** + * Retrieves the number of objects stored in the container. + * @return Number of objects in the container. + */ + function length() external view returns (uint256); + + /** + * Pushes an object into the container. + * @param _object A 32 byte value to insert into the container. + */ + function push(bytes32 _object) external; + + /** + * Pushes an object into the container. Function allows setting the global metadata since + * we'll need to touch the "length" storage slot anyway, which also contains the global + * metadata (it's an optimization). + * @param _object A 32 byte value to insert into the container. + * @param _globalMetadata New global metadata for the container. + */ + function push(bytes32 _object, bytes27 _globalMetadata) external; + + /** + * Retrieves an object from the container. + * @param _index Index of the particular object to access. + * @return 32 byte object value. + */ + function get(uint256 _index) external view returns (bytes32); + + /** + * Removes all objects after and including a given index. + * @param _index Object index to delete from. + */ + function deleteElementsAfterInclusive(uint256 _index) external; + + /** + * Removes all objects after and including a given index. Also allows setting the global + * metadata field. + * @param _index Object index to delete from. + * @param _globalMetadata New global metadata for the container. + */ + function deleteElementsAfterInclusive(uint256 _index, bytes27 _globalMetadata) external; +} diff --git a/packages/contracts/L1/rollup/IStateCommitmentChain.sol b/packages/contracts/L1/rollup/IStateCommitmentChain.sol new file mode 100644 index 0000000000000..17c4e15b52fac --- /dev/null +++ b/packages/contracts/L1/rollup/IStateCommitmentChain.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: MIT +pragma solidity >0.5.0 <0.9.0; + +/* Library Imports */ +import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; + +/** + * @title IStateCommitmentChain + */ +interface IStateCommitmentChain { + /********** + * Events * + **********/ + + event StateBatchAppended( + uint256 indexed _batchIndex, + bytes32 _batchRoot, + uint256 _batchSize, + uint256 _prevTotalElements, + bytes _extraData + ); + + event StateBatchDeleted(uint256 indexed _batchIndex, bytes32 _batchRoot); + + /******************** + * Public Functions * + ********************/ + + /** + * Retrieves the total number of elements submitted. + * @return _totalElements Total submitted elements. + */ + function getTotalElements() external view returns (uint256 _totalElements); + + /** + * Retrieves the total number of batches submitted. + * @return _totalBatches Total submitted batches. + */ + function getTotalBatches() external view returns (uint256 _totalBatches); + + /** + * Retrieves the timestamp of the last batch submitted by the sequencer. + * @return _lastSequencerTimestamp Last sequencer batch timestamp. + */ + function getLastSequencerTimestamp() external view returns (uint256 _lastSequencerTimestamp); + + /** + * Appends a batch of state roots to the chain. + * @param _batch Batch of state roots. + * @param _shouldStartAtElement Index of the element at which this batch should start. + */ + function appendStateBatch(bytes32[] calldata _batch, uint256 _shouldStartAtElement) external; + + /** + * Deletes all state roots after (and including) a given batch. + * @param _batchHeader Header of the batch to start deleting from. + */ + function deleteStateBatch(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) external; + + /** + * Verifies a batch inclusion proof. + * @param _element Hash of the element to verify a proof for. + * @param _batchHeader Header of the batch in which the element was included. + * @param _proof Merkle inclusion proof for the element. + * @return _verified Whether or not the batch inclusion proof is verified. + */ + function verifyStateCommitment( + bytes32 _element, + Lib_OVMCodec.ChainBatchHeader memory _batchHeader, + Lib_OVMCodec.ChainInclusionProof memory _proof + ) external view returns (bool _verified); + + /** + * Checks whether a given batch is still inside its fraud proof window. + * @param _batchHeader Header of the batch to check. + * @return _inside Whether or not the batch is inside the fraud proof window. + */ + function insideFraudProofWindow(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) + external + view + returns (bool _inside); +} diff --git a/packages/contracts/L1/rollup/StateCommitmentChain.sol b/packages/contracts/L1/rollup/StateCommitmentChain.sol new file mode 100644 index 0000000000000..31271f5e44be4 --- /dev/null +++ b/packages/contracts/L1/rollup/StateCommitmentChain.sol @@ -0,0 +1,309 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Library Imports */ +import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; +import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol"; +import { Lib_MerkleTree } from "../../libraries/utils/Lib_MerkleTree.sol"; + +/* Interface Imports */ +import { IStateCommitmentChain } from "./IStateCommitmentChain.sol"; +import { ICanonicalTransactionChain } from "./ICanonicalTransactionChain.sol"; +import { IBondManager } from "../verification/IBondManager.sol"; +import { IChainStorageContainer } from "./IChainStorageContainer.sol"; + +/** + * @title StateCommitmentChain + * @dev The State Commitment Chain (SCC) contract contains a list of proposed state roots which + * Proposers assert to be a result of each transaction in the Canonical Transaction Chain (CTC). + * Elements here have a 1:1 correspondence with transactions in the CTC, and should be the unique + * state root calculated off-chain by applying the canonical transactions one by one. + * + */ +contract StateCommitmentChain is IStateCommitmentChain, Lib_AddressResolver { + /************* + * Constants * + *************/ + + uint256 public FRAUD_PROOF_WINDOW; + uint256 public SEQUENCER_PUBLISH_WINDOW; + + /*************** + * Constructor * + ***************/ + + /** + * @param _libAddressManager Address of the Address Manager. + * @param _fraudProofWindow Number of seconds until fraud proof is in the finalized state. + * @param _sequencerPublishWindow Number of seconds that the sequencer is exclusively allowed + * to post state roots. + */ + constructor( + address _libAddressManager, + uint256 _fraudProofWindow, + uint256 _sequencerPublishWindow + ) Lib_AddressResolver(_libAddressManager) { + FRAUD_PROOF_WINDOW = _fraudProofWindow; + SEQUENCER_PUBLISH_WINDOW = _sequencerPublishWindow; + } + + /******************** + * Public Functions * + ********************/ + + /** + * Accesses the batch storage container. + * @return Reference to the batch storage container. + */ + function batches() public view returns (IChainStorageContainer) { + return IChainStorageContainer(resolve("ChainStorageContainer-SCC-batches")); + } + + /** + * @inheritdoc IStateCommitmentChain + */ + function getTotalElements() public view returns (uint256 _totalElements) { + (uint40 totalElements, ) = _getBatchExtraData(); + return uint256(totalElements); + } + + /** + * @inheritdoc IStateCommitmentChain + */ + function getTotalBatches() public view returns (uint256 _totalBatches) { + return batches().length(); + } + + /** + * @inheritdoc IStateCommitmentChain + */ + // slither-disable-next-line external-function + function getLastSequencerTimestamp() public view returns (uint256 _lastSequencerTimestamp) { + (, uint40 lastSequencerTimestamp) = _getBatchExtraData(); + return uint256(lastSequencerTimestamp); + } + + /** + * @inheritdoc IStateCommitmentChain + */ + // slither-disable-next-line external-function + function appendStateBatch(bytes32[] memory _batch, uint256 _shouldStartAtElement) public { + // Fail fast in to make sure our batch roots aren't accidentally made fraudulent by the + // publication of batches by some other user. + require( + _shouldStartAtElement == getTotalElements(), + "Actual batch start index does not match expected start index." + ); + + // Proposers must have previously staked at the BondManager + require( + IBondManager(resolve("BondManager")).isCollateralized(msg.sender), + "Proposer does not have enough collateral posted" + ); + + require(_batch.length > 0, "Cannot submit an empty state batch."); + + require( + getTotalElements() + _batch.length <= + ICanonicalTransactionChain(resolve("CanonicalTransactionChain")).getTotalElements(), + "Number of state roots cannot exceed the number of canonical transactions." + ); + + // Pass the block's timestamp and the publisher of the data + // to be used in the fraud proofs + _appendBatch(_batch, abi.encode(block.timestamp, msg.sender)); + } + + /** + * @inheritdoc IStateCommitmentChain + */ + // slither-disable-next-line external-function + function deleteStateBatch(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) public { + require( + msg.sender == resolve("OVM_FraudVerifier"), + "State batches can only be deleted by the OVM_FraudVerifier." + ); + + require(_isValidBatchHeader(_batchHeader), "Invalid batch header."); + + require( + insideFraudProofWindow(_batchHeader), + "State batches can only be deleted within the fraud proof window." + ); + + _deleteBatch(_batchHeader); + } + + /** + * @inheritdoc IStateCommitmentChain + */ + // slither-disable-next-line external-function + function verifyStateCommitment( + bytes32 _element, + Lib_OVMCodec.ChainBatchHeader memory _batchHeader, + Lib_OVMCodec.ChainInclusionProof memory _proof + ) public view returns (bool) { + require(_isValidBatchHeader(_batchHeader), "Invalid batch header."); + + require( + Lib_MerkleTree.verify( + _batchHeader.batchRoot, + _element, + _proof.index, + _proof.siblings, + _batchHeader.batchSize + ), + "Invalid inclusion proof." + ); + + return true; + } + + /** + * @inheritdoc IStateCommitmentChain + */ + function insideFraudProofWindow(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) + public + view + returns (bool _inside) + { + (uint256 timestamp, ) = abi.decode(_batchHeader.extraData, (uint256, address)); + + require(timestamp != 0, "Batch header timestamp cannot be zero"); + return (timestamp + FRAUD_PROOF_WINDOW) > block.timestamp; + } + + /********************** + * Internal Functions * + **********************/ + + /** + * Parses the batch context from the extra data. + * @return Total number of elements submitted. + * @return Timestamp of the last batch submitted by the sequencer. + */ + function _getBatchExtraData() internal view returns (uint40, uint40) { + bytes27 extraData = batches().getGlobalMetadata(); + + // solhint-disable max-line-length + uint40 totalElements; + uint40 lastSequencerTimestamp; + assembly { + extraData := shr(40, extraData) + totalElements := and( + extraData, + 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF + ) + lastSequencerTimestamp := shr( + 40, + and(extraData, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000) + ) + } + // solhint-enable max-line-length + + return (totalElements, lastSequencerTimestamp); + } + + /** + * Encodes the batch context for the extra data. + * @param _totalElements Total number of elements submitted. + * @param _lastSequencerTimestamp Timestamp of the last batch submitted by the sequencer. + * @return Encoded batch context. + */ + function _makeBatchExtraData(uint40 _totalElements, uint40 _lastSequencerTimestamp) + internal + pure + returns (bytes27) + { + bytes27 extraData; + assembly { + extraData := _totalElements + extraData := or(extraData, shl(40, _lastSequencerTimestamp)) + extraData := shl(40, extraData) + } + + return extraData; + } + + /** + * Appends a batch to the chain. + * @param _batch Elements within the batch. + * @param _extraData Any extra data to append to the batch. + */ + function _appendBatch(bytes32[] memory _batch, bytes memory _extraData) internal { + address sequencer = resolve("OVM_Proposer"); + (uint40 totalElements, uint40 lastSequencerTimestamp) = _getBatchExtraData(); + + if (msg.sender == sequencer) { + lastSequencerTimestamp = uint40(block.timestamp); + } else { + // We keep track of the last batch submitted by the sequencer so there's a window in + // which only the sequencer can publish state roots. A window like this just reduces + // the chance of "system breaking" state roots being published while we're still in + // testing mode. This window should be removed or significantly reduced in the future. + require( + lastSequencerTimestamp + SEQUENCER_PUBLISH_WINDOW < block.timestamp, + "Cannot publish state roots within the sequencer publication window." + ); + } + + // For efficiency reasons getMerkleRoot modifies the `_batch` argument in place + // while calculating the root hash therefore any arguments passed to it must not + // be used again afterwards + Lib_OVMCodec.ChainBatchHeader memory batchHeader = Lib_OVMCodec.ChainBatchHeader({ + batchIndex: getTotalBatches(), + batchRoot: Lib_MerkleTree.getMerkleRoot(_batch), + batchSize: _batch.length, + prevTotalElements: totalElements, + extraData: _extraData + }); + + emit StateBatchAppended( + batchHeader.batchIndex, + batchHeader.batchRoot, + batchHeader.batchSize, + batchHeader.prevTotalElements, + batchHeader.extraData + ); + + batches().push( + Lib_OVMCodec.hashBatchHeader(batchHeader), + _makeBatchExtraData( + uint40(batchHeader.prevTotalElements + batchHeader.batchSize), + lastSequencerTimestamp + ) + ); + } + + /** + * Removes a batch and all subsequent batches from the chain. + * @param _batchHeader Header of the batch to remove. + */ + function _deleteBatch(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) internal { + require(_batchHeader.batchIndex < batches().length(), "Invalid batch index."); + + require(_isValidBatchHeader(_batchHeader), "Invalid batch header."); + + // slither-disable-next-line reentrancy-events + batches().deleteElementsAfterInclusive( + _batchHeader.batchIndex, + _makeBatchExtraData(uint40(_batchHeader.prevTotalElements), 0) + ); + + // slither-disable-next-line reentrancy-events + emit StateBatchDeleted(_batchHeader.batchIndex, _batchHeader.batchRoot); + } + + /** + * Checks that a batch header matches the stored hash for the given index. + * @param _batchHeader Batch header to validate. + * @return Whether or not the header matches the stored one. + */ + function _isValidBatchHeader(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) + internal + view + returns (bool) + { + return Lib_OVMCodec.hashBatchHeader(_batchHeader) == batches().get(_batchHeader.batchIndex); + } +} diff --git a/packages/contracts/L1/verification/BondManager.sol b/packages/contracts/L1/verification/BondManager.sol new file mode 100644 index 0000000000000..9e33907db52a0 --- /dev/null +++ b/packages/contracts/L1/verification/BondManager.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Interface Imports */ +import { IBondManager } from "./IBondManager.sol"; + +/* Contract Imports */ +import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol"; + +/** + * @title BondManager + * @dev This contract is, for now, a stub of the "real" BondManager that does nothing but + * allow the "OVM_Proposer" to submit state root batches. + * + */ +contract BondManager is IBondManager, Lib_AddressResolver { + /** + * @param _libAddressManager Address of the Address Manager. + */ + constructor(address _libAddressManager) Lib_AddressResolver(_libAddressManager) {} + + /** + * @inheritdoc IBondManager + */ + // slither-disable-next-line external-function + function isCollateralized(address _who) public view returns (bool) { + // Only authenticate sequencer to submit state root batches. + return _who == resolve("OVM_Proposer"); + } +} diff --git a/packages/contracts/L1/verification/IBondManager.sol b/packages/contracts/L1/verification/IBondManager.sol new file mode 100644 index 0000000000000..beed2f5a995d7 --- /dev/null +++ b/packages/contracts/L1/verification/IBondManager.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title IBondManager + */ +interface IBondManager { + /******************** + * Public Functions * + ********************/ + + /** + * Checks whether a given address is properly collateralized and can perform actions within + * the system. + * @param _who Address to check. + * @return true if the address is properly collateralized, false otherwise. + */ + function isCollateralized(address _who) external view returns (bool); +} diff --git a/packages/contracts/L2/messaging/IL2CrossDomainMessenger.sol b/packages/contracts/L2/messaging/IL2CrossDomainMessenger.sol new file mode 100644 index 0000000000000..a7af8f1884332 --- /dev/null +++ b/packages/contracts/L2/messaging/IL2CrossDomainMessenger.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Interface Imports */ +import { ICrossDomainMessenger } from "../../libraries/bridge/ICrossDomainMessenger.sol"; + +/** + * @title IL2CrossDomainMessenger + */ +interface IL2CrossDomainMessenger is ICrossDomainMessenger { + /******************** + * Public Functions * + ********************/ + + /** + * Relays a cross domain message to a contract. + * @param _target Target contract address. + * @param _sender Message sender address. + * @param _message Message to send to the target. + * @param _messageNonce Nonce for the provided message. + */ + function relayMessage( + address _target, + address _sender, + bytes memory _message, + uint256 _messageNonce + ) external; +} diff --git a/packages/contracts/L2/messaging/IL2ERC20Bridge.sol b/packages/contracts/L2/messaging/IL2ERC20Bridge.sol new file mode 100644 index 0000000000000..b529bd9b12e0a --- /dev/null +++ b/packages/contracts/L2/messaging/IL2ERC20Bridge.sol @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title IL2ERC20Bridge + */ +interface IL2ERC20Bridge { + /********** + * Events * + **********/ + + event WithdrawalInitiated( + address indexed _l1Token, + address indexed _l2Token, + address indexed _from, + address _to, + uint256 _amount, + bytes _data + ); + + event DepositFinalized( + address indexed _l1Token, + address indexed _l2Token, + address indexed _from, + address _to, + uint256 _amount, + bytes _data + ); + + event DepositFailed( + address indexed _l1Token, + address indexed _l2Token, + address indexed _from, + address _to, + uint256 _amount, + bytes _data + ); + + /******************** + * Public Functions * + ********************/ + + /** + * @dev get the address of the corresponding L1 bridge contract. + * @return Address of the corresponding L1 bridge contract. + */ + function l1TokenBridge() external returns (address); + + /** + * @dev initiate a withdraw of some tokens to the caller's account on L1 + * @param _l2Token Address of L2 token where withdrawal was initiated. + * @param _amount Amount of the token to withdraw. + * @param _l1Gas Unused, but included for potential forward compatibility considerations. + * @param _data Optional data to forward to L1. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function withdraw( + address _l2Token, + uint256 _amount, + uint32 _l1Gas, + bytes calldata _data + ) external; + + /** + * @dev initiate a withdraw of some token to a recipient's account on L1. + * @param _l2Token Address of L2 token where withdrawal is initiated. + * @param _to L1 adress to credit the withdrawal to. + * @param _amount Amount of the token to withdraw. + * @param _l1Gas Unused, but included for potential forward compatibility considerations. + * @param _data Optional data to forward to L1. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function withdrawTo( + address _l2Token, + address _to, + uint256 _amount, + uint32 _l1Gas, + bytes calldata _data + ) external; + + /************************* + * Cross-chain Functions * + *************************/ + + /** + * @dev Complete a deposit from L1 to L2, and credits funds to the recipient's balance of this + * L2 token. This call will fail if it did not originate from a corresponding deposit in + * L1StandardTokenBridge. + * @param _l1Token Address for the l1 token this is called with + * @param _l2Token Address for the l2 token this is called with + * @param _from Account to pull the deposit from on L2. + * @param _to Address to receive the withdrawal at + * @param _amount Amount of the token to withdraw + * @param _data Data provider by the sender on L1. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function finalizeDeposit( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) external; +} diff --git a/packages/contracts/L2/messaging/L2CrossDomainMessenger.sol b/packages/contracts/L2/messaging/L2CrossDomainMessenger.sol new file mode 100644 index 0000000000000..ab3d1c85b3c4a --- /dev/null +++ b/packages/contracts/L2/messaging/L2CrossDomainMessenger.sol @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Library Imports */ +import { AddressAliasHelper } from "../../standards/AddressAliasHelper.sol"; +import { Lib_CrossDomainUtils } from "../../libraries/bridge/Lib_CrossDomainUtils.sol"; +import { Lib_DefaultValues } from "../../libraries/constants/Lib_DefaultValues.sol"; +import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; + +/* Interface Imports */ +import { IL2CrossDomainMessenger } from "./IL2CrossDomainMessenger.sol"; +import { iOVM_L2ToL1MessagePasser } from "../predeploys/iOVM_L2ToL1MessagePasser.sol"; + +/** + * @title L2CrossDomainMessenger + * @dev The L2 Cross Domain Messenger contract sends messages from L2 to L1, and is the entry point + * for L2 messages sent via the L1 Cross Domain Messenger. + * + */ +contract L2CrossDomainMessenger is IL2CrossDomainMessenger { + /************* + * Variables * + *************/ + + mapping(bytes32 => bool) public relayedMessages; + mapping(bytes32 => bool) public successfulMessages; + mapping(bytes32 => bool) public sentMessages; + uint256 public messageNonce; + address internal xDomainMsgSender = Lib_DefaultValues.DEFAULT_XDOMAIN_SENDER; + address public l1CrossDomainMessenger; + + /*************** + * Constructor * + ***************/ + + /** + * @param _l1CrossDomainMessenger Address of the L1 CrossDomainMessenger + */ + constructor(address _l1CrossDomainMessenger) { + l1CrossDomainMessenger = _l1CrossDomainMessenger; + } + + /******************** + * Public Functions * + ********************/ + + // slither-disable-next-line external-function + function xDomainMessageSender() public view returns (address) { + require( + xDomainMsgSender != Lib_DefaultValues.DEFAULT_XDOMAIN_SENDER, + "xDomainMessageSender is not set" + ); + return xDomainMsgSender; + } + + /** + * Sends a cross domain message to the target messenger. + * @param _target Target contract address. + * @param _message Message to send to the target. + * @param _gasLimit Gas limit for the provided message. + */ + // slither-disable-next-line external-function + function sendMessage( + address _target, + bytes memory _message, + uint32 _gasLimit + ) public { + bytes memory xDomainCalldata = Lib_CrossDomainUtils.encodeXDomainCalldata( + _target, + msg.sender, + _message, + messageNonce + ); + + sentMessages[keccak256(xDomainCalldata)] = true; + + // Actually send the message. + // slither-disable-next-line reentrancy-no-eth, reentrancy-events + iOVM_L2ToL1MessagePasser(Lib_PredeployAddresses.L2_TO_L1_MESSAGE_PASSER).passMessageToL1( + xDomainCalldata + ); + + // Emit an event before we bump the nonce or the nonce will be off by one. + // slither-disable-next-line reentrancy-events + emit SentMessage(_target, msg.sender, _message, messageNonce, _gasLimit); + // slither-disable-next-line reentrancy-no-eth + messageNonce += 1; + } + + /** + * Relays a cross domain message to a contract. + * @inheritdoc IL2CrossDomainMessenger + */ + // slither-disable-next-line external-function + function relayMessage( + address _target, + address _sender, + bytes memory _message, + uint256 _messageNonce + ) public { + // Since it is impossible to deploy a contract to an address on L2 which matches + // the alias of the L1CrossDomainMessenger, this check can only pass when it is called in + // the first call from of a deposit transaction. Thus reentrancy is prevented here. + require( + AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1CrossDomainMessenger, + "Provided message could not be verified." + ); + + bytes memory xDomainCalldata = Lib_CrossDomainUtils.encodeXDomainCalldata( + _target, + _sender, + _message, + _messageNonce + ); + + bytes32 xDomainCalldataHash = keccak256(xDomainCalldata); + + require( + successfulMessages[xDomainCalldataHash] == false, + "Provided message has already been received." + ); + + // Prevent calls to OVM_L2ToL1MessagePasser, which would enable + // an attacker to maliciously craft the _message to spoof + // a call from any L2 account. + if (_target == Lib_PredeployAddresses.L2_TO_L1_MESSAGE_PASSER) { + // Write to the successfulMessages mapping and return immediately. + successfulMessages[xDomainCalldataHash] = true; + return; + } + + xDomainMsgSender = _sender; + // slither-disable-next-line reentrancy-no-eth, reentrancy-events, reentrancy-benign + (bool success, ) = _target.call(_message); + // slither-disable-next-line reentrancy-benign + xDomainMsgSender = Lib_DefaultValues.DEFAULT_XDOMAIN_SENDER; + + // Mark the message as received if the call was successful. Ensures that a message can be + // relayed multiple times in the case that the call reverted. + if (success == true) { + // slither-disable-next-line reentrancy-no-eth + successfulMessages[xDomainCalldataHash] = true; + // slither-disable-next-line reentrancy-events + emit RelayedMessage(xDomainCalldataHash); + } else { + // slither-disable-next-line reentrancy-events + emit FailedRelayedMessage(xDomainCalldataHash); + } + + // Store an identifier that can be used to prove that the given message was relayed by some + // user. Gives us an easy way to pay relayers for their work. + bytes32 relayId = keccak256(abi.encodePacked(xDomainCalldata, msg.sender, block.number)); + + // slither-disable-next-line reentrancy-benign + relayedMessages[relayId] = true; + } +} diff --git a/packages/contracts/L2/messaging/L2StandardBridge.sol b/packages/contracts/L2/messaging/L2StandardBridge.sol new file mode 100644 index 0000000000000..da4e15daf1a67 --- /dev/null +++ b/packages/contracts/L2/messaging/L2StandardBridge.sol @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Interface Imports */ +import { IL1StandardBridge } from "../../L1/messaging/IL1StandardBridge.sol"; +import { IL1ERC20Bridge } from "../../L1/messaging/IL1ERC20Bridge.sol"; +import { IL2ERC20Bridge } from "./IL2ERC20Bridge.sol"; + +/* Library Imports */ +import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; +import { CrossDomainEnabled } from "../../libraries/bridge/CrossDomainEnabled.sol"; +import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; + +/* Contract Imports */ +import { IL2StandardERC20 } from "../../standards/IL2StandardERC20.sol"; + +/** + * @title L2StandardBridge + * @dev The L2 Standard bridge is a contract which works together with the L1 Standard bridge to + * enable ETH and ERC20 transitions between L1 and L2. + * This contract acts as a minter for new tokens when it hears about deposits into the L1 Standard + * bridge. + * This contract also acts as a burner of the tokens intended for withdrawal, informing the L1 + * bridge to release L1 funds. + */ +contract L2StandardBridge is IL2ERC20Bridge, CrossDomainEnabled { + /******************************** + * External Contract References * + ********************************/ + + address public l1TokenBridge; + + /*************** + * Constructor * + ***************/ + + /** + * @param _l2CrossDomainMessenger Cross-domain messenger used by this contract. + * @param _l1TokenBridge Address of the L1 bridge deployed to the main chain. + */ + constructor(address _l2CrossDomainMessenger, address _l1TokenBridge) + CrossDomainEnabled(_l2CrossDomainMessenger) + { + l1TokenBridge = _l1TokenBridge; + } + + /*************** + * Withdrawing * + ***************/ + + /** + * @inheritdoc IL2ERC20Bridge + */ + function withdraw( + address _l2Token, + uint256 _amount, + uint32 _l1Gas, + bytes calldata _data + ) external virtual { + _initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _l1Gas, _data); + } + + /** + * @inheritdoc IL2ERC20Bridge + */ + function withdrawTo( + address _l2Token, + address _to, + uint256 _amount, + uint32 _l1Gas, + bytes calldata _data + ) external virtual { + _initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _l1Gas, _data); + } + + /** + * @dev Performs the logic for withdrawals by burning the token and informing + * the L1 token Gateway of the withdrawal. + * @param _l2Token Address of L2 token where withdrawal is initiated. + * @param _from Account to pull the withdrawal from on L2. + * @param _to Account to give the withdrawal to on L1. + * @param _amount Amount of the token to withdraw. + * @param _l1Gas Unused, but included for potential forward compatibility considerations. + * @param _data Optional data to forward to L1. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function _initiateWithdrawal( + address _l2Token, + address _from, + address _to, + uint256 _amount, + uint32 _l1Gas, + bytes calldata _data + ) internal { + // When a withdrawal is initiated, we burn the withdrawer's funds to prevent subsequent L2 + // usage + // slither-disable-next-line reentrancy-events + IL2StandardERC20(_l2Token).burn(msg.sender, _amount); + + // Construct calldata for l1TokenBridge.finalizeERC20Withdrawal(_to, _amount) + // slither-disable-next-line reentrancy-events + address l1Token = IL2StandardERC20(_l2Token).l1Token(); + bytes memory message; + + if (_l2Token == Lib_PredeployAddresses.OVM_ETH) { + message = abi.encodeWithSelector( + IL1StandardBridge.finalizeETHWithdrawal.selector, + _from, + _to, + _amount, + _data + ); + } else { + message = abi.encodeWithSelector( + IL1ERC20Bridge.finalizeERC20Withdrawal.selector, + l1Token, + _l2Token, + _from, + _to, + _amount, + _data + ); + } + + // Send message up to L1 bridge + // slither-disable-next-line reentrancy-events + sendCrossDomainMessage(l1TokenBridge, _l1Gas, message); + + // slither-disable-next-line reentrancy-events + emit WithdrawalInitiated(l1Token, _l2Token, msg.sender, _to, _amount, _data); + } + + /************************************ + * Cross-chain Function: Depositing * + ************************************/ + + /** + * @inheritdoc IL2ERC20Bridge + */ + function finalizeDeposit( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) external virtual onlyFromCrossDomainAccount(l1TokenBridge) { + // Check the target token is compliant and + // verify the deposited token on L1 matches the L2 deposited token representation here + if ( + // slither-disable-next-line reentrancy-events + ERC165Checker.supportsInterface(_l2Token, 0x1d1d8b63) && + _l1Token == IL2StandardERC20(_l2Token).l1Token() + ) { + // When a deposit is finalized, we credit the account on L2 with the same amount of + // tokens. + // slither-disable-next-line reentrancy-events + IL2StandardERC20(_l2Token).mint(_to, _amount); + // slither-disable-next-line reentrancy-events + emit DepositFinalized(_l1Token, _l2Token, _from, _to, _amount, _data); + } else { + // Either the L2 token which is being deposited-into disagrees about the correct address + // of its L1 token, or does not support the correct interface. + // This should only happen if there is a malicious L2 token, or if a user somehow + // specified the wrong L2 token address to deposit into. + // In either case, we stop the process here and construct a withdrawal + // message so that users can get their funds out in some cases. + // There is no way to prevent malicious token contracts altogether, but this does limit + // user error and mitigate some forms of malicious contract behavior. + bytes memory message = abi.encodeWithSelector( + IL1ERC20Bridge.finalizeERC20Withdrawal.selector, + _l1Token, + _l2Token, + _to, // switched the _to and _from here to bounce back the deposit to the sender + _from, + _amount, + _data + ); + + // Send message up to L1 bridge + // slither-disable-next-line reentrancy-events + sendCrossDomainMessage(l1TokenBridge, 0, message); + // slither-disable-next-line reentrancy-events + emit DepositFailed(_l1Token, _l2Token, _from, _to, _amount, _data); + } + } +} diff --git a/packages/contracts/L2/messaging/L2StandardTokenFactory.sol b/packages/contracts/L2/messaging/L2StandardTokenFactory.sol new file mode 100644 index 0000000000000..edaf2ebffb940 --- /dev/null +++ b/packages/contracts/L2/messaging/L2StandardTokenFactory.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Contract Imports */ +import { L2StandardERC20 } from "../../standards/L2StandardERC20.sol"; +import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; + +/** + * @title L2StandardTokenFactory + * @dev Factory contract for creating standard L2 token representations of L1 ERC20s + * compatible with and working on the standard bridge. + */ +contract L2StandardTokenFactory { + event StandardL2TokenCreated(address indexed _l1Token, address indexed _l2Token); + + /** + * @dev Creates an instance of the standard ERC20 token on L2. + * @param _l1Token Address of the corresponding L1 token. + * @param _name ERC20 name. + * @param _symbol ERC20 symbol. + */ + function createStandardL2Token( + address _l1Token, + string memory _name, + string memory _symbol + ) external { + require(_l1Token != address(0), "Must provide L1 token address"); + + L2StandardERC20 l2Token = new L2StandardERC20( + Lib_PredeployAddresses.L2_STANDARD_BRIDGE, + _l1Token, + _name, + _symbol + ); + + emit StandardL2TokenCreated(_l1Token, address(l2Token)); + } +} diff --git a/packages/contracts/L2/predeploys/OVM_DeployerWhitelist.sol b/packages/contracts/L2/predeploys/OVM_DeployerWhitelist.sol new file mode 100644 index 0000000000000..a7a07c1183b1d --- /dev/null +++ b/packages/contracts/L2/predeploys/OVM_DeployerWhitelist.sol @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title OVM_DeployerWhitelist + * @dev The Deployer Whitelist is a temporary predeploy used to provide additional safety during the + * initial phases of our mainnet roll out. It is owned by the Optimism team, and defines accounts + * which are allowed to deploy contracts on Layer2. The Execution Manager will only allow an + * ovmCREATE or ovmCREATE2 operation to proceed if the deployer's address whitelisted. + */ +contract OVM_DeployerWhitelist { + /********** + * Events * + **********/ + + event OwnerChanged(address oldOwner, address newOwner); + event WhitelistStatusChanged(address deployer, bool whitelisted); + event WhitelistDisabled(address oldOwner); + + /********************** + * Contract Constants * + **********************/ + + // WARNING: When owner is set to address(0), the whitelist is disabled. + address public owner; + mapping(address => bool) public whitelist; + + /********************** + * Function Modifiers * + **********************/ + + /** + * Blocks functions to anyone except the contract owner. + */ + modifier onlyOwner() { + require(msg.sender == owner, "Function can only be called by the owner of this contract."); + _; + } + + /******************** + * Public Functions * + ********************/ + + /** + * Adds or removes an address from the deployment whitelist. + * @param _deployer Address to update permissions for. + * @param _isWhitelisted Whether or not the address is whitelisted. + */ + function setWhitelistedDeployer(address _deployer, bool _isWhitelisted) external onlyOwner { + whitelist[_deployer] = _isWhitelisted; + emit WhitelistStatusChanged(_deployer, _isWhitelisted); + } + + /** + * Updates the owner of this contract. + * @param _owner Address of the new owner. + */ + // slither-disable-next-line external-function + function setOwner(address _owner) public onlyOwner { + // Prevent users from setting the whitelist owner to address(0) except via + // enableArbitraryContractDeployment. If you want to burn the whitelist owner, send it to + // any other address that doesn't have a corresponding knowable private key. + require( + _owner != address(0), + "OVM_DeployerWhitelist: can only be disabled via enableArbitraryContractDeployment" + ); + + emit OwnerChanged(owner, _owner); + owner = _owner; + } + + /** + * Permanently enables arbitrary contract deployment and deletes the owner. + */ + function enableArbitraryContractDeployment() external onlyOwner { + emit WhitelistDisabled(owner); + owner = address(0); + } + + /** + * Checks whether an address is allowed to deploy contracts. + * @param _deployer Address to check. + * @return _allowed Whether or not the address can deploy contracts. + */ + function isDeployerAllowed(address _deployer) external view returns (bool) { + return (owner == address(0) || whitelist[_deployer]); + } +} diff --git a/packages/contracts/L2/predeploys/OVM_ETH.sol b/packages/contracts/L2/predeploys/OVM_ETH.sol new file mode 100644 index 0000000000000..5265745037580 --- /dev/null +++ b/packages/contracts/L2/predeploys/OVM_ETH.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Library Imports */ +import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; + +/* Contract Imports */ +import { L2StandardERC20 } from "../../standards/L2StandardERC20.sol"; + +/** + * @title OVM_ETH + * @dev The ETH predeploy provides an ERC20 interface for ETH deposited to Layer 2. Note that + * unlike on Layer 1, Layer 2 accounts do not have a balance field. + */ +contract OVM_ETH is L2StandardERC20 { + /*************** + * Constructor * + ***************/ + + constructor() + L2StandardERC20(Lib_PredeployAddresses.L2_STANDARD_BRIDGE, address(0), "Ether", "ETH") + {} + + // ETH ERC20 features are disabled until further notice. + // Discussion here: https://github.com/ethereum-optimism/optimism/discussions/1444 + + function transfer(address recipient, uint256 amount) public virtual override returns (bool) { + revert("OVM_ETH: transfer is disabled pending further community discussion."); + } + + function approve(address spender, uint256 amount) public virtual override returns (bool) { + revert("OVM_ETH: approve is disabled pending further community discussion."); + } + + function transferFrom( + address sender, + address recipient, + uint256 amount + ) public virtual override returns (bool) { + revert("OVM_ETH: transferFrom is disabled pending further community discussion."); + } + + function increaseAllowance(address spender, uint256 addedValue) + public + virtual + override + returns (bool) + { + revert("OVM_ETH: increaseAllowance is disabled pending further community discussion."); + } + + function decreaseAllowance(address spender, uint256 subtractedValue) + public + virtual + override + returns (bool) + { + revert("OVM_ETH: decreaseAllowance is disabled pending further community discussion."); + } +} diff --git a/packages/contracts/L2/predeploys/OVM_GasPriceOracle.sol b/packages/contracts/L2/predeploys/OVM_GasPriceOracle.sol new file mode 100644 index 0000000000000..69f83e0591a84 --- /dev/null +++ b/packages/contracts/L2/predeploys/OVM_GasPriceOracle.sol @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* External Imports */ +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; + +/** + * @title OVM_GasPriceOracle + * @dev This contract exposes the current l2 gas price, a measure of how congested the network + * currently is. This measure is used by the Sequencer to determine what fee to charge for + * transactions. When the system is more congested, the l2 gas price will increase and fees + * will also increase as a result. + * + * All public variables are set while generating the initial L2 state. The + * constructor doesn't run in practice as the L2 state generation script uses + * the deployed bytecode instead of running the initcode. + */ +contract OVM_GasPriceOracle is Ownable { + /************* + * Variables * + *************/ + + // Current L2 gas price + uint256 public gasPrice; + // Current L1 base fee + uint256 public l1BaseFee; + // Amortized cost of batch submission per transaction + uint256 public overhead; + // Value to scale the fee up by + uint256 public scalar; + // Number of decimals of the scalar + uint256 public decimals; + + /*************** + * Constructor * + ***************/ + + /** + * @param _owner Address that will initially own this contract. + */ + constructor(address _owner) Ownable() { + transferOwnership(_owner); + } + + /********** + * Events * + **********/ + + event GasPriceUpdated(uint256); + event L1BaseFeeUpdated(uint256); + event OverheadUpdated(uint256); + event ScalarUpdated(uint256); + event DecimalsUpdated(uint256); + + /******************** + * Public Functions * + ********************/ + + /** + * Allows the owner to modify the l2 gas price. + * @param _gasPrice New l2 gas price. + */ + // slither-disable-next-line external-function + function setGasPrice(uint256 _gasPrice) public onlyOwner { + gasPrice = _gasPrice; + emit GasPriceUpdated(_gasPrice); + } + + /** + * Allows the owner to modify the l1 base fee. + * @param _baseFee New l1 base fee + */ + // slither-disable-next-line external-function + function setL1BaseFee(uint256 _baseFee) public onlyOwner { + l1BaseFee = _baseFee; + emit L1BaseFeeUpdated(_baseFee); + } + + /** + * Allows the owner to modify the overhead. + * @param _overhead New overhead + */ + // slither-disable-next-line external-function + function setOverhead(uint256 _overhead) public onlyOwner { + overhead = _overhead; + emit OverheadUpdated(_overhead); + } + + /** + * Allows the owner to modify the scalar. + * @param _scalar New scalar + */ + // slither-disable-next-line external-function + function setScalar(uint256 _scalar) public onlyOwner { + scalar = _scalar; + emit ScalarUpdated(_scalar); + } + + /** + * Allows the owner to modify the decimals. + * @param _decimals New decimals + */ + // slither-disable-next-line external-function + function setDecimals(uint256 _decimals) public onlyOwner { + decimals = _decimals; + emit DecimalsUpdated(_decimals); + } + + /** + * Computes the L1 portion of the fee + * based on the size of the RLP encoded tx + * and the current l1BaseFee + * @param _data Unsigned RLP encoded tx, 6 elements + * @return L1 fee that should be paid for the tx + */ + // slither-disable-next-line external-function + function getL1Fee(bytes memory _data) public view returns (uint256) { + uint256 l1GasUsed = getL1GasUsed(_data); + uint256 l1Fee = l1GasUsed * l1BaseFee; + uint256 divisor = 10**decimals; + uint256 unscaled = l1Fee * scalar; + uint256 scaled = unscaled / divisor; + return scaled; + } + + // solhint-disable max-line-length + /** + * Computes the amount of L1 gas used for a transaction + * The overhead represents the per batch gas overhead of + * posting both transaction and state roots to L1 given larger + * batch sizes. + * 4 gas for 0 byte + * https://github.com/ethereum/go-ethereum/blob/9ada4a2e2c415e6b0b51c50e901336872e028872/params/protocol_params.go#L33 + * 16 gas for non zero byte + * https://github.com/ethereum/go-ethereum/blob/9ada4a2e2c415e6b0b51c50e901336872e028872/params/protocol_params.go#L87 + * This will need to be updated if calldata gas prices change + * Account for the transaction being unsigned + * Padding is added to account for lack of signature on transaction + * 1 byte for RLP V prefix + * 1 byte for V + * 1 byte for RLP R prefix + * 32 bytes for R + * 1 byte for RLP S prefix + * 32 bytes for S + * Total: 68 bytes of padding + * @param _data Unsigned RLP encoded tx, 6 elements + * @return Amount of L1 gas used for a transaction + */ + // solhint-enable max-line-length + function getL1GasUsed(bytes memory _data) public view returns (uint256) { + uint256 total = 0; + for (uint256 i = 0; i < _data.length; i++) { + if (_data[i] == 0) { + total += 4; + } else { + total += 16; + } + } + uint256 unsigned = total + overhead; + return unsigned + (68 * 16); + } +} diff --git a/packages/contracts/L2/predeploys/OVM_L2ToL1MessagePasser.sol b/packages/contracts/L2/predeploys/OVM_L2ToL1MessagePasser.sol new file mode 100644 index 0000000000000..4727a06da781c --- /dev/null +++ b/packages/contracts/L2/predeploys/OVM_L2ToL1MessagePasser.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Interface Imports */ +import { iOVM_L2ToL1MessagePasser } from "./iOVM_L2ToL1MessagePasser.sol"; + +/** + * @title OVM_L2ToL1MessagePasser + * @dev The L2 to L1 Message Passer is a utility contract which facilitate an L1 proof of the + * of a message on L2. The L1 Cross Domain Messenger performs this proof in its + * _verifyStorageProof function, which verifies the existence of the transaction hash in this + * contract's `sentMessages` mapping. + */ +contract OVM_L2ToL1MessagePasser is iOVM_L2ToL1MessagePasser { + /********************** + * Contract Variables * + **********************/ + + mapping(bytes32 => bool) public sentMessages; + + /******************** + * Public Functions * + ********************/ + + /** + * @inheritdoc iOVM_L2ToL1MessagePasser + */ + // slither-disable-next-line external-function + function passMessageToL1(bytes memory _message) public { + // Note: although this function is public, only messages sent from the + // L2CrossDomainMessenger will be relayed by the L1CrossDomainMessenger. + // This is enforced by a check in L1CrossDomainMessenger._verifyStorageProof(). + sentMessages[keccak256(abi.encodePacked(_message, msg.sender))] = true; + } +} diff --git a/packages/contracts/L2/predeploys/OVM_SequencerFeeVault.sol b/packages/contracts/L2/predeploys/OVM_SequencerFeeVault.sol new file mode 100644 index 0000000000000..ce61a8dab4a41 --- /dev/null +++ b/packages/contracts/L2/predeploys/OVM_SequencerFeeVault.sol @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Library Imports */ +import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; + +/* Contract Imports */ +import { L2StandardBridge } from "../messaging/L2StandardBridge.sol"; + +/** + * @title OVM_SequencerFeeVault + * @dev Simple holding contract for fees paid to the Sequencer. Likely to be replaced in the future + * but "good enough for now". + */ +contract OVM_SequencerFeeVault { + /************* + * Constants * + *************/ + + // Minimum ETH balance that can be withdrawn in a single withdrawal. + uint256 public constant MIN_WITHDRAWAL_AMOUNT = 15 ether; + + /************* + * Variables * + *************/ + + // Address on L1 that will hold the fees once withdrawn. Dynamically initialized within l2geth. + address public l1FeeWallet; + + /*************** + * Constructor * + ***************/ + + /** + * @param _l1FeeWallet Initial address for the L1 wallet that will hold fees once withdrawn. + * Currently HAS NO EFFECT in production because l2geth will mutate this storage slot during + * the genesis block. This is ONLY for testing purposes. + */ + constructor(address _l1FeeWallet) { + l1FeeWallet = _l1FeeWallet; + } + + /************ + * Fallback * + ************/ + + // slither-disable-next-line locked-ether + receive() external payable {} + + /******************** + * Public Functions * + ********************/ + + // slither-disable-next-line external-function + function withdraw() public { + require( + address(this).balance >= MIN_WITHDRAWAL_AMOUNT, + // solhint-disable-next-line max-line-length + "OVM_SequencerFeeVault: withdrawal amount must be greater than minimum withdrawal amount" + ); + + L2StandardBridge(Lib_PredeployAddresses.L2_STANDARD_BRIDGE).withdrawTo( + Lib_PredeployAddresses.OVM_ETH, + l1FeeWallet, + address(this).balance, + 0, + bytes("") + ); + } +} diff --git a/packages/contracts/L2/predeploys/WETH9.sol b/packages/contracts/L2/predeploys/WETH9.sol new file mode 100644 index 0000000000000..7bb4ab4dde576 --- /dev/null +++ b/packages/contracts/L2/predeploys/WETH9.sol @@ -0,0 +1,756 @@ +// Copyright (C) 2015, 2016, 2017 Dapphub + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +pragma solidity >=0.4.22 <0.6; + +contract WETH9 { + string public name = "Wrapped Ether"; + string public symbol = "WETH"; + uint8 public decimals = 18; + + event Approval(address indexed src, address indexed guy, uint wad); + event Transfer(address indexed src, address indexed dst, uint wad); + event Deposit(address indexed dst, uint wad); + event Withdrawal(address indexed src, uint wad); + + mapping (address => uint) public balanceOf; + mapping (address => mapping (address => uint)) public allowance; + + function() external payable { + deposit(); + } + function deposit() public payable { + balanceOf[msg.sender] += msg.value; + emit Deposit(msg.sender, msg.value); + } + function withdraw(uint wad) public { + require(balanceOf[msg.sender] >= wad); + balanceOf[msg.sender] -= wad; + msg.sender.transfer(wad); + emit Withdrawal(msg.sender, wad); + } + + function totalSupply() public view returns (uint) { + return address(this).balance; + } + + function approve(address guy, uint wad) public returns (bool) { + allowance[msg.sender][guy] = wad; + emit Approval(msg.sender, guy, wad); + return true; + } + + function transfer(address dst, uint wad) public returns (bool) { + return transferFrom(msg.sender, dst, wad); + } + + function transferFrom(address src, address dst, uint wad) + public + returns (bool) + { + require(balanceOf[src] >= wad); + + if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) { + require(allowance[src][msg.sender] >= wad); + allowance[src][msg.sender] -= wad; + } + + balanceOf[src] -= wad; + balanceOf[dst] += wad; + + emit Transfer(src, dst, wad); + + return true; + } +} + + +/* + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + +*/ diff --git a/packages/contracts/L2/predeploys/iOVM_L1BlockNumber.sol b/packages/contracts/L2/predeploys/iOVM_L1BlockNumber.sol new file mode 100644 index 0000000000000..76c956d9226e2 --- /dev/null +++ b/packages/contracts/L2/predeploys/iOVM_L1BlockNumber.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title iOVM_L1BlockNumber + */ +interface iOVM_L1BlockNumber { + /******************** + * Public Functions * + ********************/ + + /** + * @return Block number of L1 + */ + function getL1BlockNumber() external view returns (uint256); +} diff --git a/packages/contracts/L2/predeploys/iOVM_L2ToL1MessagePasser.sol b/packages/contracts/L2/predeploys/iOVM_L2ToL1MessagePasser.sol new file mode 100644 index 0000000000000..1f799f2175cfb --- /dev/null +++ b/packages/contracts/L2/predeploys/iOVM_L2ToL1MessagePasser.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title iOVM_L2ToL1MessagePasser + */ +interface iOVM_L2ToL1MessagePasser { + /********** + * Events * + **********/ + + event L2ToL1Message(uint256 _nonce, address _sender, bytes _data); + + /******************** + * Public Functions * + ********************/ + + /** + * Passes a message to L1. + * @param _message Message to pass to L1. + */ + function passMessageToL1(bytes calldata _message) external; +} diff --git a/packages/contracts/chugsplash/L1ChugSplashProxy.sol b/packages/contracts/chugsplash/L1ChugSplashProxy.sol new file mode 100644 index 0000000000000..58e8e53be30db --- /dev/null +++ b/packages/contracts/chugsplash/L1ChugSplashProxy.sol @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +import { iL1ChugSplashDeployer } from "./interfaces/iL1ChugSplashDeployer.sol"; + +/** + * @title L1ChugSplashProxy + * @dev Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added + * functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty! + * + * Note for future developers: do NOT make anything in this contract 'public' unless you know what + * you're doing. Anything public can potentially have a function signature that conflicts with a + * signature attached to the implementation contract. Public functions SHOULD always have the + * 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that + * modifier. And there almost certainly is not a good reason to not have that modifier. Beware! + */ +contract L1ChugSplashProxy { + /************* + * Constants * + *************/ + + // "Magic" prefix. When prepended to some arbitrary bytecode and used to create a contract, the + // appended bytecode will be deployed as given. + bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3; + + // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) + bytes32 internal constant IMPLEMENTATION_KEY = + 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + + // bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1) + bytes32 internal constant OWNER_KEY = + 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; + + /*************** + * Constructor * + ***************/ + + /** + * @param _owner Address of the initial contract owner. + */ + constructor(address _owner) { + _setOwner(_owner); + } + + /********************** + * Function Modifiers * + **********************/ + + /** + * Blocks a function from being called when the parent signals that the system should be paused + * via an isUpgrading function. + */ + modifier onlyWhenNotPaused() { + address owner = _getOwner(); + + // We do a low-level call because there's no guarantee that the owner actually *is* an + // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and + // it turns out that it isn't the right type of contract. + (bool success, bytes memory returndata) = owner.staticcall( + abi.encodeWithSelector(iL1ChugSplashDeployer.isUpgrading.selector) + ); + + // If the call was unsuccessful then we assume that there's no "isUpgrading" method and we + // can just continue as normal. We also expect that the return value is exactly 32 bytes + // long. If this isn't the case then we can safely ignore the result. + if (success && returndata.length == 32) { + // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the + // case that the isUpgrading function returned something other than 0 or 1. But we only + // really care about the case where this value is 0 (= false). + uint256 ret = abi.decode(returndata, (uint256)); + require(ret == 0, "L1ChugSplashProxy: system is currently being upgraded"); + } + + _; + } + + /** + * Makes a proxy call instead of triggering the given function when the caller is either the + * owner or the zero address. Caller can only ever be the zero address if this function is + * being called off-chain via eth_call, which is totally fine and can be convenient for + * client-side tooling. Avoids situations where the proxy and implementation share a sighash + * and the proxy function ends up being called instead of the implementation one. + * + * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If there's a + * way for someone to send a transaction with msg.sender == address(0) in any real context then + * we have much bigger problems. Primary reason to include this additional allowed sender is + * because the owner address can be changed dynamically and we do not want clients to have to + * keep track of the current owner in order to make an eth_call that doesn't trigger the + * proxied contract. + */ + // slither-disable-next-line incorrect-modifier + modifier proxyCallIfNotOwner() { + if (msg.sender == _getOwner() || msg.sender == address(0)) { + _; + } else { + // This WILL halt the call frame on completion. + _doProxyCall(); + } + } + + /********************* + * Fallback Function * + *********************/ + + // slither-disable-next-line locked-ether + fallback() external payable { + // Proxy call by default. + _doProxyCall(); + } + + /******************** + * Public Functions * + ********************/ + + /** + * Sets the code that should be running behind this proxy. Note that this scheme is a bit + * different from the standard proxy scheme where one would typically deploy the code + * separately and then set the implementation address. We're doing it this way because it gives + * us a lot more freedom on the client side. Can only be triggered by the contract owner. + * @param _code New contract code to run inside this contract. + */ + // slither-disable-next-line external-function + function setCode(bytes memory _code) public proxyCallIfNotOwner { + // Get the code hash of the current implementation. + address implementation = _getImplementation(); + + // If the code hash matches the new implementation then we return early. + if (keccak256(_code) == _getAccountCodeHash(implementation)) { + return; + } + + // Create the deploycode by appending the magic prefix. + bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code); + + // Deploy the code and set the new implementation address. + address newImplementation; + assembly { + newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode)) + } + + // Check that the code was actually deployed correctly. I'm not sure if you can ever + // actually fail this check. Should only happen if the contract creation from above runs + // out of gas but this parent execution thread does NOT run out of gas. Seems like we + // should be doing this check anyway though. + require( + _getAccountCodeHash(newImplementation) == keccak256(_code), + "L1ChugSplashProxy: code was not correctly deployed." + ); + + _setImplementation(newImplementation); + } + + /** + * Modifies some storage slot within the proxy contract. Gives us a lot of power to perform + * upgrades in a more transparent way. Only callable by the owner. + * @param _key Storage key to modify. + * @param _value New value for the storage key. + */ + // slither-disable-next-line external-function + function setStorage(bytes32 _key, bytes32 _value) public proxyCallIfNotOwner { + assembly { + sstore(_key, _value) + } + } + + /** + * Changes the owner of the proxy contract. Only callable by the owner. + * @param _owner New owner of the proxy contract. + */ + // slither-disable-next-line external-function + function setOwner(address _owner) public proxyCallIfNotOwner { + _setOwner(_owner); + } + + /** + * Queries the owner of the proxy contract. Can only be called by the owner OR by making an + * eth_call and setting the "from" address to address(0). + * @return Owner address. + */ + // slither-disable-next-line external-function + function getOwner() public proxyCallIfNotOwner returns (address) { + return _getOwner(); + } + + /** + * Queries the implementation address. Can only be called by the owner OR by making an + * eth_call and setting the "from" address to address(0). + * @return Implementation address. + */ + // slither-disable-next-line external-function + function getImplementation() public proxyCallIfNotOwner returns (address) { + return _getImplementation(); + } + + /********************** + * Internal Functions * + **********************/ + + /** + * Sets the implementation address. + * @param _implementation New implementation address. + */ + function _setImplementation(address _implementation) internal { + assembly { + sstore(IMPLEMENTATION_KEY, _implementation) + } + } + + /** + * Queries the implementation address. + * @return Implementation address. + */ + function _getImplementation() internal view returns (address) { + address implementation; + assembly { + implementation := sload(IMPLEMENTATION_KEY) + } + return implementation; + } + + /** + * Changes the owner of the proxy contract. + * @param _owner New owner of the proxy contract. + */ + function _setOwner(address _owner) internal { + assembly { + sstore(OWNER_KEY, _owner) + } + } + + /** + * Queries the owner of the proxy contract. + * @return Owner address. + */ + function _getOwner() internal view returns (address) { + address owner; + assembly { + owner := sload(OWNER_KEY) + } + return owner; + } + + /** + * Gets the code hash for a given account. + * @param _account Address of the account to get a code hash for. + * @return Code hash for the account. + */ + function _getAccountCodeHash(address _account) internal view returns (bytes32) { + bytes32 codeHash; + assembly { + codeHash := extcodehash(_account) + } + return codeHash; + } + + /** + * Performs the proxy call via a delegatecall. + */ + function _doProxyCall() internal onlyWhenNotPaused { + address implementation = _getImplementation(); + + require(implementation != address(0), "L1ChugSplashProxy: implementation is not set yet"); + + assembly { + // Copy calldata into memory at 0x0....calldatasize. + calldatacopy(0x0, 0x0, calldatasize()) + + // Perform the delegatecall, make sure to pass all available gas. + let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0) + + // Copy returndata into memory at 0x0....returndatasize. Note that this *will* + // overwrite the calldata that we just copied into memory but that doesn't really + // matter because we'll be returning in a second anyway. + returndatacopy(0x0, 0x0, returndatasize()) + + // Success == 0 means a revert. We'll revert too and pass the data up. + if iszero(success) { + revert(0x0, returndatasize()) + } + + // Otherwise we'll just return and pass the data up. + return(0x0, returndatasize()) + } + } +} diff --git a/packages/contracts/chugsplash/interfaces/iL1ChugSplashDeployer.sol b/packages/contracts/chugsplash/interfaces/iL1ChugSplashDeployer.sol new file mode 100644 index 0000000000000..d2724494fcc4d --- /dev/null +++ b/packages/contracts/chugsplash/interfaces/iL1ChugSplashDeployer.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title iL1ChugSplashDeployer + */ +interface iL1ChugSplashDeployer { + function isUpgrading() external view returns (bool); +} diff --git a/packages/contracts/libraries/bridge/CrossDomainEnabled.sol b/packages/contracts/libraries/bridge/CrossDomainEnabled.sol new file mode 100644 index 0000000000000..28a6566026c22 --- /dev/null +++ b/packages/contracts/libraries/bridge/CrossDomainEnabled.sol @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: MIT +pragma solidity >0.5.0 <0.9.0; + +/* Interface Imports */ +import { ICrossDomainMessenger } from "./ICrossDomainMessenger.sol"; + +/** + * @title CrossDomainEnabled + * @dev Helper contract for contracts performing cross-domain communications + * + * Compiler used: defined by inheriting contract + */ +contract CrossDomainEnabled { + /************* + * Variables * + *************/ + + // Messenger contract used to send and recieve messages from the other domain. + address public messenger; + + /*************** + * Constructor * + ***************/ + + /** + * @param _messenger Address of the CrossDomainMessenger on the current layer. + */ + constructor(address _messenger) { + messenger = _messenger; + } + + /********************** + * Function Modifiers * + **********************/ + + /** + * Enforces that the modified function is only callable by a specific cross-domain account. + * @param _sourceDomainAccount The only account on the originating domain which is + * authenticated to call this function. + */ + modifier onlyFromCrossDomainAccount(address _sourceDomainAccount) { + require( + msg.sender == address(getCrossDomainMessenger()), + "OVM_XCHAIN: messenger contract unauthenticated" + ); + + require( + getCrossDomainMessenger().xDomainMessageSender() == _sourceDomainAccount, + "OVM_XCHAIN: wrong sender of cross-domain message" + ); + + _; + } + + /********************** + * Internal Functions * + **********************/ + + /** + * Gets the messenger, usually from storage. This function is exposed in case a child contract + * needs to override. + * @return The address of the cross-domain messenger contract which should be used. + */ + function getCrossDomainMessenger() internal virtual returns (ICrossDomainMessenger) { + return ICrossDomainMessenger(messenger); + } + + /**q + * Sends a message to an account on another domain + * @param _crossDomainTarget The intended recipient on the destination domain + * @param _message The data to send to the target (usually calldata to a function with + * `onlyFromCrossDomainAccount()`) + * @param _gasLimit The gasLimit for the receipt of the message on the target domain. + */ + function sendCrossDomainMessage( + address _crossDomainTarget, + uint32 _gasLimit, + bytes memory _message + ) internal { + // slither-disable-next-line reentrancy-events, reentrancy-benign + getCrossDomainMessenger().sendMessage(_crossDomainTarget, _message, _gasLimit); + } +} diff --git a/packages/contracts/libraries/bridge/ICrossDomainMessenger.sol b/packages/contracts/libraries/bridge/ICrossDomainMessenger.sol new file mode 100644 index 0000000000000..543a671ec6f83 --- /dev/null +++ b/packages/contracts/libraries/bridge/ICrossDomainMessenger.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity >0.5.0 <0.9.0; + +/** + * @title ICrossDomainMessenger + */ +interface ICrossDomainMessenger { + /********** + * Events * + **********/ + + event SentMessage( + address indexed target, + address sender, + bytes message, + uint256 messageNonce, + uint256 gasLimit + ); + event RelayedMessage(bytes32 indexed msgHash); + event FailedRelayedMessage(bytes32 indexed msgHash); + + /************* + * Variables * + *************/ + + function xDomainMessageSender() external view returns (address); + + /******************** + * Public Functions * + ********************/ + + /** + * Sends a cross domain message to the target messenger. + * @param _target Target contract address. + * @param _message Message to send to the target. + * @param _gasLimit Gas limit for the provided message. + */ + function sendMessage( + address _target, + bytes calldata _message, + uint32 _gasLimit + ) external; +} diff --git a/packages/contracts/libraries/bridge/Lib_CrossDomainUtils.sol b/packages/contracts/libraries/bridge/Lib_CrossDomainUtils.sol new file mode 100644 index 0000000000000..62c788d084a81 --- /dev/null +++ b/packages/contracts/libraries/bridge/Lib_CrossDomainUtils.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title Lib_CrossDomainUtils + */ +library Lib_CrossDomainUtils { + /** + * Generates the correct cross domain calldata for a message. + * @param _target Target contract address. + * @param _sender Message sender address. + * @param _message Message to send to the target. + * @param _messageNonce Nonce for the provided message. + * @return ABI encoded cross domain calldata. + */ + function encodeXDomainCalldata( + address _target, + address _sender, + bytes memory _message, + uint256 _messageNonce + ) internal pure returns (bytes memory) { + return + abi.encodeWithSignature( + "relayMessage(address,address,bytes,uint256)", + _target, + _sender, + _message, + _messageNonce + ); + } +} diff --git a/packages/contracts/libraries/codec/Lib_OVMCodec.sol b/packages/contracts/libraries/codec/Lib_OVMCodec.sol new file mode 100644 index 0000000000000..75332d94df9d5 --- /dev/null +++ b/packages/contracts/libraries/codec/Lib_OVMCodec.sol @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Library Imports */ +import { Lib_RLPReader } from "../rlp/Lib_RLPReader.sol"; +import { Lib_RLPWriter } from "../rlp/Lib_RLPWriter.sol"; +import { Lib_BytesUtils } from "../utils/Lib_BytesUtils.sol"; +import { Lib_Bytes32Utils } from "../utils/Lib_Bytes32Utils.sol"; + +/** + * @title Lib_OVMCodec + */ +library Lib_OVMCodec { + /********* + * Enums * + *********/ + + enum QueueOrigin { + SEQUENCER_QUEUE, + L1TOL2_QUEUE + } + + /*********** + * Structs * + ***********/ + + struct EVMAccount { + uint256 nonce; + uint256 balance; + bytes32 storageRoot; + bytes32 codeHash; + } + + struct ChainBatchHeader { + uint256 batchIndex; + bytes32 batchRoot; + uint256 batchSize; + uint256 prevTotalElements; + bytes extraData; + } + + struct ChainInclusionProof { + uint256 index; + bytes32[] siblings; + } + + struct Transaction { + uint256 timestamp; + uint256 blockNumber; + QueueOrigin l1QueueOrigin; + address l1TxOrigin; + address entrypoint; + uint256 gasLimit; + bytes data; + } + + struct TransactionChainElement { + bool isSequenced; + uint256 queueIndex; // QUEUED TX ONLY + uint256 timestamp; // SEQUENCER TX ONLY + uint256 blockNumber; // SEQUENCER TX ONLY + bytes txData; // SEQUENCER TX ONLY + } + + struct QueueElement { + bytes32 transactionHash; + uint40 timestamp; + uint40 blockNumber; + } + + /********************** + * Internal Functions * + **********************/ + + /** + * Encodes a standard OVM transaction. + * @param _transaction OVM transaction to encode. + * @return Encoded transaction bytes. + */ + function encodeTransaction(Transaction memory _transaction) + internal + pure + returns (bytes memory) + { + return + abi.encodePacked( + _transaction.timestamp, + _transaction.blockNumber, + _transaction.l1QueueOrigin, + _transaction.l1TxOrigin, + _transaction.entrypoint, + _transaction.gasLimit, + _transaction.data + ); + } + + /** + * Hashes a standard OVM transaction. + * @param _transaction OVM transaction to encode. + * @return Hashed transaction + */ + function hashTransaction(Transaction memory _transaction) internal pure returns (bytes32) { + return keccak256(encodeTransaction(_transaction)); + } + + /** + * @notice Decodes an RLP-encoded account state into a useful struct. + * @param _encoded RLP-encoded account state. + * @return Account state struct. + */ + function decodeEVMAccount(bytes memory _encoded) internal pure returns (EVMAccount memory) { + Lib_RLPReader.RLPItem[] memory accountState = Lib_RLPReader.readList(_encoded); + + return + EVMAccount({ + nonce: Lib_RLPReader.readUint256(accountState[0]), + balance: Lib_RLPReader.readUint256(accountState[1]), + storageRoot: Lib_RLPReader.readBytes32(accountState[2]), + codeHash: Lib_RLPReader.readBytes32(accountState[3]) + }); + } + + /** + * Calculates a hash for a given batch header. + * @param _batchHeader Header to hash. + * @return Hash of the header. + */ + function hashBatchHeader(Lib_OVMCodec.ChainBatchHeader memory _batchHeader) + internal + pure + returns (bytes32) + { + return + keccak256( + abi.encode( + _batchHeader.batchRoot, + _batchHeader.batchSize, + _batchHeader.prevTotalElements, + _batchHeader.extraData + ) + ); + } +} diff --git a/packages/contracts/libraries/constants/Lib_DefaultValues.sol b/packages/contracts/libraries/constants/Lib_DefaultValues.sol new file mode 100644 index 0000000000000..62f7296e594ac --- /dev/null +++ b/packages/contracts/libraries/constants/Lib_DefaultValues.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title Lib_DefaultValues + */ +library Lib_DefaultValues { + // The default x-domain message sender being set to a non-zero value makes + // deployment a bit more expensive, but in exchange the refund on every call to + // `relayMessage` by the L1 and L2 messengers will be higher. + address internal constant DEFAULT_XDOMAIN_SENDER = 0x000000000000000000000000000000000000dEaD; +} diff --git a/packages/contracts/libraries/constants/Lib_PredeployAddresses.sol b/packages/contracts/libraries/constants/Lib_PredeployAddresses.sol new file mode 100644 index 0000000000000..e853bdab1085a --- /dev/null +++ b/packages/contracts/libraries/constants/Lib_PredeployAddresses.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title Lib_PredeployAddresses + */ +library Lib_PredeployAddresses { + address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000; + address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001; + address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002; + address payable internal constant OVM_ETH = payable(0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000); + address internal constant L2_CROSS_DOMAIN_MESSENGER = + 0x4200000000000000000000000000000000000007; + address internal constant LIB_ADDRESS_MANAGER = 0x4200000000000000000000000000000000000008; + address internal constant PROXY_EOA = 0x4200000000000000000000000000000000000009; + address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010; + address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011; + address internal constant L2_STANDARD_TOKEN_FACTORY = + 0x4200000000000000000000000000000000000012; + address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013; +} diff --git a/packages/contracts/libraries/resolver/Lib_AddressManager.sol b/packages/contracts/libraries/resolver/Lib_AddressManager.sol new file mode 100644 index 0000000000000..81390476ec43b --- /dev/null +++ b/packages/contracts/libraries/resolver/Lib_AddressManager.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* External Imports */ +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; + +/** + * @title Lib_AddressManager + */ +contract Lib_AddressManager is Ownable { + /********** + * Events * + **********/ + + event AddressSet(string indexed _name, address _newAddress, address _oldAddress); + + /************* + * Variables * + *************/ + + mapping(bytes32 => address) private addresses; + + /******************** + * Public Functions * + ********************/ + + /** + * Changes the address associated with a particular name. + * @param _name String name to associate an address with. + * @param _address Address to associate with the name. + */ + function setAddress(string memory _name, address _address) external onlyOwner { + bytes32 nameHash = _getNameHash(_name); + address oldAddress = addresses[nameHash]; + addresses[nameHash] = _address; + + emit AddressSet(_name, _address, oldAddress); + } + + /** + * Retrieves the address associated with a given name. + * @param _name Name to retrieve an address for. + * @return Address associated with the given name. + */ + function getAddress(string memory _name) external view returns (address) { + return addresses[_getNameHash(_name)]; + } + + /********************** + * Internal Functions * + **********************/ + + /** + * Computes the hash of a name. + * @param _name Name to compute a hash for. + * @return Hash of the given name. + */ + function _getNameHash(string memory _name) internal pure returns (bytes32) { + return keccak256(abi.encodePacked(_name)); + } +} diff --git a/packages/contracts/libraries/resolver/Lib_AddressResolver.sol b/packages/contracts/libraries/resolver/Lib_AddressResolver.sol new file mode 100644 index 0000000000000..47e8e00b198b6 --- /dev/null +++ b/packages/contracts/libraries/resolver/Lib_AddressResolver.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Library Imports */ +import { Lib_AddressManager } from "./Lib_AddressManager.sol"; + +/** + * @title Lib_AddressResolver + */ +abstract contract Lib_AddressResolver { + /************* + * Variables * + *************/ + + Lib_AddressManager public libAddressManager; + + /*************** + * Constructor * + ***************/ + + /** + * @param _libAddressManager Address of the Lib_AddressManager. + */ + constructor(address _libAddressManager) { + libAddressManager = Lib_AddressManager(_libAddressManager); + } + + /******************** + * Public Functions * + ********************/ + + /** + * Resolves the address associated with a given name. + * @param _name Name to resolve an address for. + * @return Address associated with the given name. + */ + function resolve(string memory _name) public view returns (address) { + return libAddressManager.getAddress(_name); + } +} diff --git a/packages/contracts/libraries/resolver/Lib_ResolvedDelegateProxy.sol b/packages/contracts/libraries/resolver/Lib_ResolvedDelegateProxy.sol new file mode 100644 index 0000000000000..47cd0caec3fe9 --- /dev/null +++ b/packages/contracts/libraries/resolver/Lib_ResolvedDelegateProxy.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Library Imports */ +import { Lib_AddressManager } from "./Lib_AddressManager.sol"; + +/** + * @title Lib_ResolvedDelegateProxy + */ +contract Lib_ResolvedDelegateProxy { + /************* + * Variables * + *************/ + + // Using mappings to store fields to avoid overwriting storage slots in the + // implementation contract. For example, instead of storing these fields at + // storage slot `0` & `1`, they are stored at `keccak256(key + slot)`. + // See: https://solidity.readthedocs.io/en/v0.7.0/internals/layout_in_storage.html + // NOTE: Do not use this code in your own contract system. + // There is a known flaw in this contract, and we will remove it from the repository + // in the near future. Due to the very limited way that we are using it, this flaw is + // not an issue in our system. + mapping(address => string) private implementationName; + mapping(address => Lib_AddressManager) private addressManager; + + /*************** + * Constructor * + ***************/ + + /** + * @param _libAddressManager Address of the Lib_AddressManager. + * @param _implementationName implementationName of the contract to proxy to. + */ + constructor(address _libAddressManager, string memory _implementationName) { + addressManager[address(this)] = Lib_AddressManager(_libAddressManager); + implementationName[address(this)] = _implementationName; + } + + /********************* + * Fallback Function * + *********************/ + + fallback() external payable { + address target = addressManager[address(this)].getAddress( + (implementationName[address(this)]) + ); + + require(target != address(0), "Target address must be initialized."); + + // slither-disable-next-line controlled-delegatecall + (bool success, bytes memory returndata) = target.delegatecall(msg.data); + + if (success == true) { + assembly { + return(add(returndata, 0x20), mload(returndata)) + } + } else { + assembly { + revert(add(returndata, 0x20), mload(returndata)) + } + } + } +} diff --git a/packages/contracts/libraries/rlp/Lib_RLPReader.sol b/packages/contracts/libraries/rlp/Lib_RLPReader.sol new file mode 100644 index 0000000000000..fe9b708508ced --- /dev/null +++ b/packages/contracts/libraries/rlp/Lib_RLPReader.sol @@ -0,0 +1,388 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title Lib_RLPReader + * @dev Adapted from "RLPReader" by Hamdi Allam (hamdi.allam97@gmail.com). + */ +library Lib_RLPReader { + /************* + * Constants * + *************/ + + uint256 internal constant MAX_LIST_LENGTH = 32; + + /********* + * Enums * + *********/ + + enum RLPItemType { + DATA_ITEM, + LIST_ITEM + } + + /*********** + * Structs * + ***********/ + + struct RLPItem { + uint256 length; + uint256 ptr; + } + + /********************** + * Internal Functions * + **********************/ + + /** + * Converts bytes to a reference to memory position and length. + * @param _in Input bytes to convert. + * @return Output memory reference. + */ + function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) { + uint256 ptr; + assembly { + ptr := add(_in, 32) + } + + return RLPItem({ length: _in.length, ptr: ptr }); + } + + /** + * Reads an RLP list value into a list of RLP items. + * @param _in RLP list value. + * @return Decoded RLP list items. + */ + function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) { + (uint256 listOffset, , RLPItemType itemType) = _decodeLength(_in); + + require(itemType == RLPItemType.LIST_ITEM, "Invalid RLP list value."); + + // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by + // writing to the length. Since we can't know the number of RLP items without looping over + // the entire input, we'd have to loop twice to accurately size this array. It's easier to + // simply set a reasonable maximum list length and decrease the size before we finish. + RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH); + + uint256 itemCount = 0; + uint256 offset = listOffset; + while (offset < _in.length) { + require(itemCount < MAX_LIST_LENGTH, "Provided RLP list exceeds max list length."); + + (uint256 itemOffset, uint256 itemLength, ) = _decodeLength( + RLPItem({ length: _in.length - offset, ptr: _in.ptr + offset }) + ); + + out[itemCount] = RLPItem({ length: itemLength + itemOffset, ptr: _in.ptr + offset }); + + itemCount += 1; + offset += itemOffset + itemLength; + } + + // Decrease the array size to match the actual item count. + assembly { + mstore(out, itemCount) + } + + return out; + } + + /** + * Reads an RLP list value into a list of RLP items. + * @param _in RLP list value. + * @return Decoded RLP list items. + */ + function readList(bytes memory _in) internal pure returns (RLPItem[] memory) { + return readList(toRLPItem(_in)); + } + + /** + * Reads an RLP bytes value into bytes. + * @param _in RLP bytes value. + * @return Decoded bytes. + */ + function readBytes(RLPItem memory _in) internal pure returns (bytes memory) { + (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in); + + require(itemType == RLPItemType.DATA_ITEM, "Invalid RLP bytes value."); + + return _copy(_in.ptr, itemOffset, itemLength); + } + + /** + * Reads an RLP bytes value into bytes. + * @param _in RLP bytes value. + * @return Decoded bytes. + */ + function readBytes(bytes memory _in) internal pure returns (bytes memory) { + return readBytes(toRLPItem(_in)); + } + + /** + * Reads an RLP string value into a string. + * @param _in RLP string value. + * @return Decoded string. + */ + function readString(RLPItem memory _in) internal pure returns (string memory) { + return string(readBytes(_in)); + } + + /** + * Reads an RLP string value into a string. + * @param _in RLP string value. + * @return Decoded string. + */ + function readString(bytes memory _in) internal pure returns (string memory) { + return readString(toRLPItem(_in)); + } + + /** + * Reads an RLP bytes32 value into a bytes32. + * @param _in RLP bytes32 value. + * @return Decoded bytes32. + */ + function readBytes32(RLPItem memory _in) internal pure returns (bytes32) { + require(_in.length <= 33, "Invalid RLP bytes32 value."); + + (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in); + + require(itemType == RLPItemType.DATA_ITEM, "Invalid RLP bytes32 value."); + + uint256 ptr = _in.ptr + itemOffset; + bytes32 out; + assembly { + out := mload(ptr) + + // Shift the bytes over to match the item size. + if lt(itemLength, 32) { + out := div(out, exp(256, sub(32, itemLength))) + } + } + + return out; + } + + /** + * Reads an RLP bytes32 value into a bytes32. + * @param _in RLP bytes32 value. + * @return Decoded bytes32. + */ + function readBytes32(bytes memory _in) internal pure returns (bytes32) { + return readBytes32(toRLPItem(_in)); + } + + /** + * Reads an RLP uint256 value into a uint256. + * @param _in RLP uint256 value. + * @return Decoded uint256. + */ + function readUint256(RLPItem memory _in) internal pure returns (uint256) { + return uint256(readBytes32(_in)); + } + + /** + * Reads an RLP uint256 value into a uint256. + * @param _in RLP uint256 value. + * @return Decoded uint256. + */ + function readUint256(bytes memory _in) internal pure returns (uint256) { + return readUint256(toRLPItem(_in)); + } + + /** + * Reads an RLP bool value into a bool. + * @param _in RLP bool value. + * @return Decoded bool. + */ + function readBool(RLPItem memory _in) internal pure returns (bool) { + require(_in.length == 1, "Invalid RLP boolean value."); + + uint256 ptr = _in.ptr; + uint256 out; + assembly { + out := byte(0, mload(ptr)) + } + + require(out == 0 || out == 1, "Lib_RLPReader: Invalid RLP boolean value, must be 0 or 1"); + + return out != 0; + } + + /** + * Reads an RLP bool value into a bool. + * @param _in RLP bool value. + * @return Decoded bool. + */ + function readBool(bytes memory _in) internal pure returns (bool) { + return readBool(toRLPItem(_in)); + } + + /** + * Reads an RLP address value into a address. + * @param _in RLP address value. + * @return Decoded address. + */ + function readAddress(RLPItem memory _in) internal pure returns (address) { + if (_in.length == 1) { + return address(0); + } + + require(_in.length == 21, "Invalid RLP address value."); + + return address(uint160(readUint256(_in))); + } + + /** + * Reads an RLP address value into a address. + * @param _in RLP address value. + * @return Decoded address. + */ + function readAddress(bytes memory _in) internal pure returns (address) { + return readAddress(toRLPItem(_in)); + } + + /** + * Reads the raw bytes of an RLP item. + * @param _in RLP item to read. + * @return Raw RLP bytes. + */ + function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) { + return _copy(_in); + } + + /********************* + * Private Functions * + *********************/ + + /** + * Decodes the length of an RLP item. + * @param _in RLP item to decode. + * @return Offset of the encoded data. + * @return Length of the encoded data. + * @return RLP item type (LIST_ITEM or DATA_ITEM). + */ + function _decodeLength(RLPItem memory _in) + private + pure + returns ( + uint256, + uint256, + RLPItemType + ) + { + require(_in.length > 0, "RLP item cannot be null."); + + uint256 ptr = _in.ptr; + uint256 prefix; + assembly { + prefix := byte(0, mload(ptr)) + } + + if (prefix <= 0x7f) { + // Single byte. + + return (0, 1, RLPItemType.DATA_ITEM); + } else if (prefix <= 0xb7) { + // Short string. + + // slither-disable-next-line variable-scope + uint256 strLen = prefix - 0x80; + + require(_in.length > strLen, "Invalid RLP short string."); + + return (1, strLen, RLPItemType.DATA_ITEM); + } else if (prefix <= 0xbf) { + // Long string. + uint256 lenOfStrLen = prefix - 0xb7; + + require(_in.length > lenOfStrLen, "Invalid RLP long string length."); + + uint256 strLen; + assembly { + // Pick out the string length. + strLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfStrLen))) + } + + require(_in.length > lenOfStrLen + strLen, "Invalid RLP long string."); + + return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM); + } else if (prefix <= 0xf7) { + // Short list. + // slither-disable-next-line variable-scope + uint256 listLen = prefix - 0xc0; + + require(_in.length > listLen, "Invalid RLP short list."); + + return (1, listLen, RLPItemType.LIST_ITEM); + } else { + // Long list. + uint256 lenOfListLen = prefix - 0xf7; + + require(_in.length > lenOfListLen, "Invalid RLP long list length."); + + uint256 listLen; + assembly { + // Pick out the list length. + listLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfListLen))) + } + + require(_in.length > lenOfListLen + listLen, "Invalid RLP long list."); + + return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM); + } + } + + /** + * Copies the bytes from a memory location. + * @param _src Pointer to the location to read from. + * @param _offset Offset to start reading from. + * @param _length Number of bytes to read. + * @return Copied bytes. + */ + function _copy( + uint256 _src, + uint256 _offset, + uint256 _length + ) private pure returns (bytes memory) { + bytes memory out = new bytes(_length); + if (out.length == 0) { + return out; + } + + uint256 src = _src + _offset; + uint256 dest; + assembly { + dest := add(out, 32) + } + + // Copy over as many complete words as we can. + for (uint256 i = 0; i < _length / 32; i++) { + assembly { + mstore(dest, mload(src)) + } + + src += 32; + dest += 32; + } + + // Pick out the remaining bytes. + uint256 mask; + unchecked { + mask = 256**(32 - (_length % 32)) - 1; + } + + assembly { + mstore(dest, or(and(mload(src), not(mask)), and(mload(dest), mask))) + } + return out; + } + + /** + * Copies an RLP item into bytes. + * @param _in RLP item to copy. + * @return Copied bytes. + */ + function _copy(RLPItem memory _in) private pure returns (bytes memory) { + return _copy(_in.ptr, 0, _in.length); + } +} diff --git a/packages/contracts/libraries/rlp/Lib_RLPWriter.sol b/packages/contracts/libraries/rlp/Lib_RLPWriter.sol new file mode 100644 index 0000000000000..bd41d81c0e06f --- /dev/null +++ b/packages/contracts/libraries/rlp/Lib_RLPWriter.sol @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title Lib_RLPWriter + * @author Bakaoh (with modifications) + */ +library Lib_RLPWriter { + /********************** + * Internal Functions * + **********************/ + + /** + * RLP encodes a byte string. + * @param _in The byte string to encode. + * @return The RLP encoded string in bytes. + */ + function writeBytes(bytes memory _in) internal pure returns (bytes memory) { + bytes memory encoded; + + if (_in.length == 1 && uint8(_in[0]) < 128) { + encoded = _in; + } else { + encoded = abi.encodePacked(_writeLength(_in.length, 128), _in); + } + + return encoded; + } + + /** + * RLP encodes a list of RLP encoded byte byte strings. + * @param _in The list of RLP encoded byte strings. + * @return The RLP encoded list of items in bytes. + */ + function writeList(bytes[] memory _in) internal pure returns (bytes memory) { + bytes memory list = _flatten(_in); + return abi.encodePacked(_writeLength(list.length, 192), list); + } + + /** + * RLP encodes a string. + * @param _in The string to encode. + * @return The RLP encoded string in bytes. + */ + function writeString(string memory _in) internal pure returns (bytes memory) { + return writeBytes(bytes(_in)); + } + + /** + * RLP encodes an address. + * @param _in The address to encode. + * @return The RLP encoded address in bytes. + */ + function writeAddress(address _in) internal pure returns (bytes memory) { + return writeBytes(abi.encodePacked(_in)); + } + + /** + * RLP encodes a uint. + * @param _in The uint256 to encode. + * @return The RLP encoded uint256 in bytes. + */ + function writeUint(uint256 _in) internal pure returns (bytes memory) { + return writeBytes(_toBinary(_in)); + } + + /** + * RLP encodes a bool. + * @param _in The bool to encode. + * @return The RLP encoded bool in bytes. + */ + function writeBool(bool _in) internal pure returns (bytes memory) { + bytes memory encoded = new bytes(1); + encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80)); + return encoded; + } + + /********************* + * Private Functions * + *********************/ + + /** + * Encode the first byte, followed by the `len` in binary form if `length` is more than 55. + * @param _len The length of the string or the payload. + * @param _offset 128 if item is string, 192 if item is list. + * @return RLP encoded bytes. + */ + function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) { + bytes memory encoded; + + if (_len < 56) { + encoded = new bytes(1); + encoded[0] = bytes1(uint8(_len) + uint8(_offset)); + } else { + uint256 lenLen; + uint256 i = 1; + while (_len / i != 0) { + lenLen++; + i *= 256; + } + + encoded = new bytes(lenLen + 1); + encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55); + for (i = 1; i <= lenLen; i++) { + encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256)); + } + } + + return encoded; + } + + /** + * Encode integer in big endian binary form with no leading zeroes. + * @notice TODO: This should be optimized with assembly to save gas costs. + * @param _x The integer to encode. + * @return RLP encoded bytes. + */ + function _toBinary(uint256 _x) private pure returns (bytes memory) { + bytes memory b = abi.encodePacked(_x); + + uint256 i = 0; + for (; i < 32; i++) { + if (b[i] != 0) { + break; + } + } + + bytes memory res = new bytes(32 - i); + for (uint256 j = 0; j < res.length; j++) { + res[j] = b[i++]; + } + + return res; + } + + /** + * Copies a piece of memory to another location. + * @notice From: https://github.com/Arachnid/solidity-stringutils/blob/master/src/strings.sol. + * @param _dest Destination location. + * @param _src Source location. + * @param _len Length of memory to copy. + */ + function _memcpy( + uint256 _dest, + uint256 _src, + uint256 _len + ) private pure { + uint256 dest = _dest; + uint256 src = _src; + uint256 len = _len; + + for (; len >= 32; len -= 32) { + assembly { + mstore(dest, mload(src)) + } + dest += 32; + src += 32; + } + + uint256 mask; + unchecked { + mask = 256**(32 - len) - 1; + } + assembly { + let srcpart := and(mload(src), not(mask)) + let destpart := and(mload(dest), mask) + mstore(dest, or(destpart, srcpart)) + } + } + + /** + * Flattens a list of byte strings into one byte string. + * @notice From: https://github.com/sammayo/solidity-rlp-encoder/blob/master/RLPEncode.sol. + * @param _list List of byte strings to flatten. + * @return The flattened byte string. + */ + function _flatten(bytes[] memory _list) private pure returns (bytes memory) { + if (_list.length == 0) { + return new bytes(0); + } + + uint256 len; + uint256 i = 0; + for (; i < _list.length; i++) { + len += _list[i].length; + } + + bytes memory flattened = new bytes(len); + uint256 flattenedPtr; + assembly { + flattenedPtr := add(flattened, 0x20) + } + + for (i = 0; i < _list.length; i++) { + bytes memory item = _list[i]; + + uint256 listPtr; + assembly { + listPtr := add(item, 0x20) + } + + _memcpy(flattenedPtr, listPtr, item.length); + flattenedPtr += _list[i].length; + } + + return flattened; + } +} diff --git a/packages/contracts/libraries/trie/Lib_MerkleTrie.sol b/packages/contracts/libraries/trie/Lib_MerkleTrie.sol new file mode 100644 index 0000000000000..d25154de78bfc --- /dev/null +++ b/packages/contracts/libraries/trie/Lib_MerkleTrie.sol @@ -0,0 +1,304 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Library Imports */ +import { Lib_BytesUtils } from "../utils/Lib_BytesUtils.sol"; +import { Lib_RLPReader } from "../rlp/Lib_RLPReader.sol"; +import { Lib_RLPWriter } from "../rlp/Lib_RLPWriter.sol"; + +/** + * @title Lib_MerkleTrie + */ +library Lib_MerkleTrie { + /******************* + * Data Structures * + *******************/ + + enum NodeType { + BranchNode, + ExtensionNode, + LeafNode + } + + struct TrieNode { + bytes encoded; + Lib_RLPReader.RLPItem[] decoded; + } + + /********************** + * Contract Constants * + **********************/ + + // TREE_RADIX determines the number of elements per branch node. + uint256 constant TREE_RADIX = 16; + // Branch nodes have TREE_RADIX elements plus an additional `value` slot. + uint256 constant BRANCH_NODE_LENGTH = TREE_RADIX + 1; + // Leaf nodes and extension nodes always have two elements, a `path` and a `value`. + uint256 constant LEAF_OR_EXTENSION_NODE_LENGTH = 2; + + // Prefixes are prepended to the `path` within a leaf or extension node and + // allow us to differentiate between the two node types. `ODD` or `EVEN` is + // determined by the number of nibbles within the unprefixed `path`. If the + // number of nibbles if even, we need to insert an extra padding nibble so + // the resulting prefixed `path` has an even number of nibbles. + uint8 constant PREFIX_EXTENSION_EVEN = 0; + uint8 constant PREFIX_EXTENSION_ODD = 1; + uint8 constant PREFIX_LEAF_EVEN = 2; + uint8 constant PREFIX_LEAF_ODD = 3; + + // Just a utility constant. RLP represents `NULL` as 0x80. + bytes1 constant RLP_NULL = bytes1(0x80); + + /********************** + * Internal Functions * + **********************/ + + /** + * @notice Verifies a proof that a given key/value pair is present in the + * Merkle trie. + * @param _key Key of the node to search for, as a hex string. + * @param _value Value of the node to search for, as a hex string. + * @param _proof Merkle trie inclusion proof for the desired node. Unlike + * traditional Merkle trees, this proof is executed top-down and consists + * of a list of RLP-encoded nodes that make a path down to the target node. + * @param _root Known root of the Merkle trie. Used to verify that the + * included proof is correctly constructed. + * @return _verified `true` if the k/v pair exists in the trie, `false` otherwise. + */ + function verifyInclusionProof( + bytes memory _key, + bytes memory _value, + bytes memory _proof, + bytes32 _root + ) internal pure returns (bool _verified) { + (bool exists, bytes memory value) = get(_key, _proof, _root); + + return (exists && Lib_BytesUtils.equal(_value, value)); + } + + /** + * @notice Retrieves the value associated with a given key. + * @param _key Key to search for, as hex bytes. + * @param _proof Merkle trie inclusion proof for the key. + * @param _root Known root of the Merkle trie. + * @return _exists Whether or not the key exists. + * @return _value Value of the key if it exists. + */ + function get( + bytes memory _key, + bytes memory _proof, + bytes32 _root + ) internal pure returns (bool _exists, bytes memory _value) { + TrieNode[] memory proof = _parseProof(_proof); + (uint256 pathLength, bytes memory keyRemainder, bool isFinalNode) = _walkNodePath( + proof, + _key, + _root + ); + + bool exists = keyRemainder.length == 0; + + require(exists || isFinalNode, "Provided proof is invalid."); + + bytes memory value = exists ? _getNodeValue(proof[pathLength - 1]) : bytes(""); + + return (exists, value); + } + + /********************* + * Private Functions * + *********************/ + + /** + * @notice Walks through a proof using a provided key. + * @param _proof Inclusion proof to walk through. + * @param _key Key to use for the walk. + * @param _root Known root of the trie. + * @return _pathLength Length of the final path + * @return _keyRemainder Portion of the key remaining after the walk. + * @return _isFinalNode Whether or not we've hit a dead end. + */ + function _walkNodePath( + TrieNode[] memory _proof, + bytes memory _key, + bytes32 _root + ) + private + pure + returns ( + uint256 _pathLength, + bytes memory _keyRemainder, + bool _isFinalNode + ) + { + uint256 pathLength = 0; + bytes memory key = Lib_BytesUtils.toNibbles(_key); + + bytes32 currentNodeID = _root; + uint256 currentKeyIndex = 0; + uint256 currentKeyIncrement = 0; + TrieNode memory currentNode; + + // Proof is top-down, so we start at the first element (root). + for (uint256 i = 0; i < _proof.length; i++) { + currentNode = _proof[i]; + currentKeyIndex += currentKeyIncrement; + + // Keep track of the proof elements we actually need. + // It's expensive to resize arrays, so this simply reduces gas costs. + pathLength += 1; + + if (currentKeyIndex == 0) { + // First proof element is always the root node. + require(keccak256(currentNode.encoded) == currentNodeID, "Invalid root hash"); + } else if (currentNode.encoded.length >= 32) { + // Nodes 32 bytes or larger are hashed inside branch nodes. + require( + keccak256(currentNode.encoded) == currentNodeID, + "Invalid large internal hash" + ); + } else { + // Nodes smaller than 31 bytes aren't hashed. + require( + Lib_BytesUtils.toBytes32(currentNode.encoded) == currentNodeID, + "Invalid internal node hash" + ); + } + + if (currentNode.decoded.length == BRANCH_NODE_LENGTH) { + if (currentKeyIndex == key.length) { + // We've hit the end of the key + // meaning the value should be within this branch node. + break; + } else { + // We're not at the end of the key yet. + // Figure out what the next node ID should be and continue. + uint8 branchKey = uint8(key[currentKeyIndex]); + Lib_RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey]; + currentNodeID = _getNodeID(nextNode); + currentKeyIncrement = 1; + continue; + } + } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) { + bytes memory path = _getNodePath(currentNode); + uint8 prefix = uint8(path[0]); + uint8 offset = 2 - (prefix % 2); + bytes memory pathRemainder = Lib_BytesUtils.slice(path, offset); + bytes memory keyRemainder = Lib_BytesUtils.slice(key, currentKeyIndex); + uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder); + + if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) { + if ( + pathRemainder.length == sharedNibbleLength && + keyRemainder.length == sharedNibbleLength + ) { + // The key within this leaf matches our key exactly. + // Increment the key index to reflect that we have no remainder. + currentKeyIndex += sharedNibbleLength; + } + + // We've hit a leaf node, so our next node should be NULL. + currentNodeID = bytes32(RLP_NULL); + break; + } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) { + if (sharedNibbleLength != pathRemainder.length) { + // Our extension node is not identical to the remainder. + // We've hit the end of this path + // updates will need to modify this extension. + currentNodeID = bytes32(RLP_NULL); + break; + } else { + // Our extension shares some nibbles. + // Carry on to the next node. + currentNodeID = _getNodeID(currentNode.decoded[1]); + currentKeyIncrement = sharedNibbleLength; + continue; + } + } else { + revert("Received a node with an unknown prefix"); + } + } else { + revert("Received an unparseable node."); + } + } + + // If our node ID is NULL, then we're at a dead end. + bool isFinalNode = currentNodeID == bytes32(RLP_NULL); + return (pathLength, Lib_BytesUtils.slice(key, currentKeyIndex), isFinalNode); + } + + /** + * @notice Parses an RLP-encoded proof into something more useful. + * @param _proof RLP-encoded proof to parse. + * @return _parsed Proof parsed into easily accessible structs. + */ + function _parseProof(bytes memory _proof) private pure returns (TrieNode[] memory _parsed) { + Lib_RLPReader.RLPItem[] memory nodes = Lib_RLPReader.readList(_proof); + TrieNode[] memory proof = new TrieNode[](nodes.length); + + for (uint256 i = 0; i < nodes.length; i++) { + bytes memory encoded = Lib_RLPReader.readBytes(nodes[i]); + proof[i] = TrieNode({ encoded: encoded, decoded: Lib_RLPReader.readList(encoded) }); + } + + return proof; + } + + /** + * @notice Picks out the ID for a node. Node ID is referred to as the + * "hash" within the specification, but nodes < 32 bytes are not actually + * hashed. + * @param _node Node to pull an ID for. + * @return _nodeID ID for the node, depending on the size of its contents. + */ + function _getNodeID(Lib_RLPReader.RLPItem memory _node) private pure returns (bytes32 _nodeID) { + bytes memory nodeID; + + if (_node.length < 32) { + // Nodes smaller than 32 bytes are RLP encoded. + nodeID = Lib_RLPReader.readRawBytes(_node); + } else { + // Nodes 32 bytes or larger are hashed. + nodeID = Lib_RLPReader.readBytes(_node); + } + + return Lib_BytesUtils.toBytes32(nodeID); + } + + /** + * @notice Gets the path for a leaf or extension node. + * @param _node Node to get a path for. + * @return _path Node path, converted to an array of nibbles. + */ + function _getNodePath(TrieNode memory _node) private pure returns (bytes memory _path) { + return Lib_BytesUtils.toNibbles(Lib_RLPReader.readBytes(_node.decoded[0])); + } + + /** + * @notice Gets the path for a node. + * @param _node Node to get a value for. + * @return _value Node value, as hex bytes. + */ + function _getNodeValue(TrieNode memory _node) private pure returns (bytes memory _value) { + return Lib_RLPReader.readBytes(_node.decoded[_node.decoded.length - 1]); + } + + /** + * @notice Utility; determines the number of nibbles shared between two + * nibble arrays. + * @param _a First nibble array. + * @param _b Second nibble array. + * @return _shared Number of shared nibbles. + */ + function _getSharedNibbleLength(bytes memory _a, bytes memory _b) + private + pure + returns (uint256 _shared) + { + uint256 i = 0; + while (_a.length > i && _b.length > i && _a[i] == _b[i]) { + i++; + } + return i; + } +} diff --git a/packages/contracts/libraries/trie/Lib_SecureMerkleTrie.sol b/packages/contracts/libraries/trie/Lib_SecureMerkleTrie.sol new file mode 100644 index 0000000000000..3ef14fc29188c --- /dev/null +++ b/packages/contracts/libraries/trie/Lib_SecureMerkleTrie.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Library Imports */ +import { Lib_MerkleTrie } from "./Lib_MerkleTrie.sol"; + +/** + * @title Lib_SecureMerkleTrie + */ +library Lib_SecureMerkleTrie { + /********************** + * Internal Functions * + **********************/ + + /** + * @notice Verifies a proof that a given key/value pair is present in the + * Merkle trie. + * @param _key Key of the node to search for, as a hex string. + * @param _value Value of the node to search for, as a hex string. + * @param _proof Merkle trie inclusion proof for the desired node. Unlike + * traditional Merkle trees, this proof is executed top-down and consists + * of a list of RLP-encoded nodes that make a path down to the target node. + * @param _root Known root of the Merkle trie. Used to verify that the + * included proof is correctly constructed. + * @return _verified `true` if the k/v pair exists in the trie, `false` otherwise. + */ + function verifyInclusionProof( + bytes memory _key, + bytes memory _value, + bytes memory _proof, + bytes32 _root + ) internal pure returns (bool _verified) { + bytes memory key = _getSecureKey(_key); + return Lib_MerkleTrie.verifyInclusionProof(key, _value, _proof, _root); + } + + /** + * @notice Retrieves the value associated with a given key. + * @param _key Key to search for, as hex bytes. + * @param _proof Merkle trie inclusion proof for the key. + * @param _root Known root of the Merkle trie. + * @return _exists Whether or not the key exists. + * @return _value Value of the key if it exists. + */ + function get( + bytes memory _key, + bytes memory _proof, + bytes32 _root + ) internal pure returns (bool _exists, bytes memory _value) { + bytes memory key = _getSecureKey(_key); + return Lib_MerkleTrie.get(key, _proof, _root); + } + + /********************* + * Private Functions * + *********************/ + + /** + * Computes the secure counterpart to a key. + * @param _key Key to get a secure key from. + * @return _secureKey Secure version of the key. + */ + function _getSecureKey(bytes memory _key) private pure returns (bytes memory _secureKey) { + return abi.encodePacked(keccak256(_key)); + } +} diff --git a/packages/contracts/libraries/utils/Lib_Buffer.sol b/packages/contracts/libraries/utils/Lib_Buffer.sol new file mode 100644 index 0000000000000..86ec1322267d0 --- /dev/null +++ b/packages/contracts/libraries/utils/Lib_Buffer.sol @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title Lib_Buffer + * @dev This library implements a bytes32 storage array with some additional gas-optimized + * functionality. In particular, it encodes its length as a uint40, and tightly packs this with an + * overwritable "extra data" field so we can store more information with a single SSTORE. + */ +library Lib_Buffer { + /************* + * Libraries * + *************/ + + using Lib_Buffer for Buffer; + + /*********** + * Structs * + ***********/ + + struct Buffer { + bytes32 context; + mapping(uint256 => bytes32) buf; + } + + struct BufferContext { + // Stores the length of the array. Uint40 is way more elements than we'll ever reasonably + // need in an array and we get an extra 27 bytes of extra data to play with. + uint40 length; + // Arbitrary extra data that can be modified whenever the length is updated. Useful for + // squeezing out some gas optimizations. + bytes27 extraData; + } + + /********************** + * Internal Functions * + **********************/ + + /** + * Pushes a single element to the buffer. + * @param _self Buffer to access. + * @param _value Value to push to the buffer. + * @param _extraData Global extra data. + */ + function push( + Buffer storage _self, + bytes32 _value, + bytes27 _extraData + ) internal { + BufferContext memory ctx = _self.getContext(); + + _self.buf[ctx.length] = _value; + + // Bump the global index and insert our extra data, then save the context. + ctx.length++; + ctx.extraData = _extraData; + _self.setContext(ctx); + } + + /** + * Pushes a single element to the buffer. + * @param _self Buffer to access. + * @param _value Value to push to the buffer. + */ + function push(Buffer storage _self, bytes32 _value) internal { + BufferContext memory ctx = _self.getContext(); + + _self.push(_value, ctx.extraData); + } + + /** + * Retrieves an element from the buffer. + * @param _self Buffer to access. + * @param _index Element index to retrieve. + * @return Value of the element at the given index. + */ + function get(Buffer storage _self, uint256 _index) internal view returns (bytes32) { + BufferContext memory ctx = _self.getContext(); + + require(_index < ctx.length, "Index out of bounds."); + + return _self.buf[_index]; + } + + /** + * Deletes all elements after (and including) a given index. + * @param _self Buffer to access. + * @param _index Index of the element to delete from (inclusive). + * @param _extraData Optional global extra data. + */ + function deleteElementsAfterInclusive( + Buffer storage _self, + uint40 _index, + bytes27 _extraData + ) internal { + BufferContext memory ctx = _self.getContext(); + + require(_index < ctx.length, "Index out of bounds."); + + // Set our length and extra data, save the context. + ctx.length = _index; + ctx.extraData = _extraData; + _self.setContext(ctx); + } + + /** + * Deletes all elements after (and including) a given index. + * @param _self Buffer to access. + * @param _index Index of the element to delete from (inclusive). + */ + function deleteElementsAfterInclusive(Buffer storage _self, uint40 _index) internal { + BufferContext memory ctx = _self.getContext(); + _self.deleteElementsAfterInclusive(_index, ctx.extraData); + } + + /** + * Retrieves the current global index. + * @param _self Buffer to access. + * @return Current global index. + */ + function getLength(Buffer storage _self) internal view returns (uint40) { + BufferContext memory ctx = _self.getContext(); + return ctx.length; + } + + /** + * Changes current global extra data. + * @param _self Buffer to access. + * @param _extraData New global extra data. + */ + function setExtraData(Buffer storage _self, bytes27 _extraData) internal { + BufferContext memory ctx = _self.getContext(); + ctx.extraData = _extraData; + _self.setContext(ctx); + } + + /** + * Retrieves the current global extra data. + * @param _self Buffer to access. + * @return Current global extra data. + */ + function getExtraData(Buffer storage _self) internal view returns (bytes27) { + BufferContext memory ctx = _self.getContext(); + return ctx.extraData; + } + + /** + * Sets the current buffer context. + * @param _self Buffer to access. + * @param _ctx Current buffer context. + */ + function setContext(Buffer storage _self, BufferContext memory _ctx) internal { + bytes32 context; + uint40 length = _ctx.length; + bytes27 extraData = _ctx.extraData; + assembly { + context := length + context := or(context, extraData) + } + + if (_self.context != context) { + _self.context = context; + } + } + + /** + * Retrieves the current buffer context. + * @param _self Buffer to access. + * @return Current buffer context. + */ + function getContext(Buffer storage _self) internal view returns (BufferContext memory) { + bytes32 context = _self.context; + uint40 length; + bytes27 extraData; + assembly { + length := and( + context, + 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF + ) + extraData := and( + context, + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000 + ) + } + + return BufferContext({ length: length, extraData: extraData }); + } +} diff --git a/packages/contracts/libraries/utils/Lib_Bytes32Utils.sol b/packages/contracts/libraries/utils/Lib_Bytes32Utils.sol new file mode 100644 index 0000000000000..abd23ede46ae2 --- /dev/null +++ b/packages/contracts/libraries/utils/Lib_Bytes32Utils.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title Lib_Byte32Utils + */ +library Lib_Bytes32Utils { + /********************** + * Internal Functions * + **********************/ + + /** + * Converts a bytes32 value to a boolean. Anything non-zero will be converted to "true." + * @param _in Input bytes32 value. + * @return Bytes32 as a boolean. + */ + function toBool(bytes32 _in) internal pure returns (bool) { + return _in != 0; + } + + /** + * Converts a boolean to a bytes32 value. + * @param _in Input boolean value. + * @return Boolean as a bytes32. + */ + function fromBool(bool _in) internal pure returns (bytes32) { + return bytes32(uint256(_in ? 1 : 0)); + } + + /** + * Converts a bytes32 value to an address. Takes the *last* 20 bytes. + * @param _in Input bytes32 value. + * @return Bytes32 as an address. + */ + function toAddress(bytes32 _in) internal pure returns (address) { + return address(uint160(uint256(_in))); + } + + /** + * Converts an address to a bytes32. + * @param _in Input address value. + * @return Address as a bytes32. + */ + function fromAddress(address _in) internal pure returns (bytes32) { + return bytes32(uint256(uint160(_in))); + } +} diff --git a/packages/contracts/libraries/utils/Lib_BytesUtils.sol b/packages/contracts/libraries/utils/Lib_BytesUtils.sol new file mode 100644 index 0000000000000..f8f81cd552d5e --- /dev/null +++ b/packages/contracts/libraries/utils/Lib_BytesUtils.sol @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title Lib_BytesUtils + */ +library Lib_BytesUtils { + /********************** + * Internal Functions * + **********************/ + + function slice( + bytes memory _bytes, + uint256 _start, + uint256 _length + ) internal pure returns (bytes memory) { + require(_length + 31 >= _length, "slice_overflow"); + require(_start + _length >= _start, "slice_overflow"); + require(_bytes.length >= _start + _length, "slice_outOfBounds"); + + bytes memory tempBytes; + + assembly { + switch iszero(_length) + case 0 { + // Get a location of some free memory and store it in tempBytes as + // Solidity does for memory variables. + tempBytes := mload(0x40) + + // The first word of the slice result is potentially a partial + // word read from the original array. To read it, we calculate + // the length of that partial word and start copying that many + // bytes into the array. The first word we copy will start with + // data we don't care about, but the last `lengthmod` bytes will + // land at the beginning of the contents of the new array. When + // we're done copying, we overwrite the full first word with + // the actual length of the slice. + let lengthmod := and(_length, 31) + + // The multiplication in the next line is necessary + // because when slicing multiples of 32 bytes (lengthmod == 0) + // the following copy loop was copying the origin's length + // and then ending prematurely not copying everything it should. + let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) + let end := add(mc, _length) + + for { + // The multiplication in the next line has the same exact purpose + // as the one above. + let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) + } lt(mc, end) { + mc := add(mc, 0x20) + cc := add(cc, 0x20) + } { + mstore(mc, mload(cc)) + } + + mstore(tempBytes, _length) + + //update free-memory pointer + //allocating the array padded to 32 bytes like the compiler does now + mstore(0x40, and(add(mc, 31), not(31))) + } + //if we want a zero-length slice let's just return a zero-length array + default { + tempBytes := mload(0x40) + + //zero out the 32 bytes slice we are about to return + //we need to do it because Solidity does not garbage collect + mstore(tempBytes, 0) + + mstore(0x40, add(tempBytes, 0x20)) + } + } + + return tempBytes; + } + + function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) { + if (_start >= _bytes.length) { + return bytes(""); + } + + return slice(_bytes, _start, _bytes.length - _start); + } + + function toBytes32(bytes memory _bytes) internal pure returns (bytes32) { + if (_bytes.length < 32) { + bytes32 ret; + assembly { + ret := mload(add(_bytes, 32)) + } + return ret; + } + + return abi.decode(_bytes, (bytes32)); // will truncate if input length > 32 bytes + } + + function toUint256(bytes memory _bytes) internal pure returns (uint256) { + return uint256(toBytes32(_bytes)); + } + + function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) { + bytes memory nibbles = new bytes(_bytes.length * 2); + + for (uint256 i = 0; i < _bytes.length; i++) { + nibbles[i * 2] = _bytes[i] >> 4; + nibbles[i * 2 + 1] = bytes1(uint8(_bytes[i]) % 16); + } + + return nibbles; + } + + function fromNibbles(bytes memory _bytes) internal pure returns (bytes memory) { + bytes memory ret = new bytes(_bytes.length / 2); + + for (uint256 i = 0; i < ret.length; i++) { + ret[i] = (_bytes[i * 2] << 4) | (_bytes[i * 2 + 1]); + } + + return ret; + } + + function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) { + return keccak256(_bytes) == keccak256(_other); + } +} diff --git a/packages/contracts/libraries/utils/Lib_MerkleTree.sol b/packages/contracts/libraries/utils/Lib_MerkleTree.sol new file mode 100644 index 0000000000000..344643407cd47 --- /dev/null +++ b/packages/contracts/libraries/utils/Lib_MerkleTree.sol @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/** + * @title Lib_MerkleTree + * @author River Keefer + */ +library Lib_MerkleTree { + /********************** + * Internal Functions * + **********************/ + + /** + * Calculates a merkle root for a list of 32-byte leaf hashes. WARNING: If the number + * of leaves passed in is not a power of two, it pads out the tree with zero hashes. + * If you do not know the original length of elements for the tree you are verifying, then + * this may allow empty leaves past _elements.length to pass a verification check down the line. + * Note that the _elements argument is modified, therefore it must not be used again afterwards + * @param _elements Array of hashes from which to generate a merkle root. + * @return Merkle root of the leaves, with zero hashes for non-powers-of-two (see above). + */ + function getMerkleRoot(bytes32[] memory _elements) internal pure returns (bytes32) { + require(_elements.length > 0, "Lib_MerkleTree: Must provide at least one leaf hash."); + + if (_elements.length == 1) { + return _elements[0]; + } + + uint256[16] memory defaults = [ + 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563, + 0x633dc4d7da7256660a892f8f1604a44b5432649cc8ec5cb3ced4c4e6ac94dd1d, + 0x890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d, + 0x3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd8, + 0xecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da, + 0xdefff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da5, + 0x617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d7, + 0x292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead, + 0xe1cea92ed99acdcb045a6726b2f87107e8a61620a232cf4d7d5b5766b3952e10, + 0x7ad66c0a68c72cb89e4fb4303841966e4062a76ab97451e3b9fb526a5ceb7f82, + 0xe026cc5a4aed3c22a58cbd3d2ac754c9352c5436f638042dca99034e83636516, + 0x3d04cffd8b46a874edf5cfae63077de85f849a660426697b06a829c70dd1409c, + 0xad676aa337a485e4728a0b240d92b3ef7b3c372d06d189322bfd5f61f1e7203e, + 0xa2fca4a49658f9fab7aa63289c91b7c7b6c832a6d0e69334ff5b0a3483d09dab, + 0x4ebfd9cd7bca2505f7bef59cc1c12ecc708fff26ae4af19abe852afe9e20c862, + 0x2def10d13dd169f550f578bda343d9717a138562e0093b380a1120789d53cf10 + ]; + + // Reserve memory space for our hashes. + bytes memory buf = new bytes(64); + + // We'll need to keep track of left and right siblings. + bytes32 leftSibling; + bytes32 rightSibling; + + // Number of non-empty nodes at the current depth. + uint256 rowSize = _elements.length; + + // Current depth, counting from 0 at the leaves + uint256 depth = 0; + + // Common sub-expressions + uint256 halfRowSize; // rowSize / 2 + bool rowSizeIsOdd; // rowSize % 2 == 1 + + while (rowSize > 1) { + halfRowSize = rowSize / 2; + rowSizeIsOdd = rowSize % 2 == 1; + + for (uint256 i = 0; i < halfRowSize; i++) { + leftSibling = _elements[(2 * i)]; + rightSibling = _elements[(2 * i) + 1]; + assembly { + mstore(add(buf, 32), leftSibling) + mstore(add(buf, 64), rightSibling) + } + + _elements[i] = keccak256(buf); + } + + if (rowSizeIsOdd) { + leftSibling = _elements[rowSize - 1]; + rightSibling = bytes32(defaults[depth]); + assembly { + mstore(add(buf, 32), leftSibling) + mstore(add(buf, 64), rightSibling) + } + + _elements[halfRowSize] = keccak256(buf); + } + + rowSize = halfRowSize + (rowSizeIsOdd ? 1 : 0); + depth++; + } + + return _elements[0]; + } + + /** + * Verifies a merkle branch for the given leaf hash. Assumes the original length + * of leaves generated is a known, correct input, and does not return true for indices + * extending past that index (even if _siblings would be otherwise valid.) + * @param _root The Merkle root to verify against. + * @param _leaf The leaf hash to verify inclusion of. + * @param _index The index in the tree of this leaf. + * @param _siblings Array of sibline nodes in the inclusion proof, starting from depth 0 + * (bottom of the tree). + * @param _totalLeaves The total number of leaves originally passed into. + * @return Whether or not the merkle branch and leaf passes verification. + */ + function verify( + bytes32 _root, + bytes32 _leaf, + uint256 _index, + bytes32[] memory _siblings, + uint256 _totalLeaves + ) internal pure returns (bool) { + require(_totalLeaves > 0, "Lib_MerkleTree: Total leaves must be greater than zero."); + + require(_index < _totalLeaves, "Lib_MerkleTree: Index out of bounds."); + + require( + _siblings.length == _ceilLog2(_totalLeaves), + "Lib_MerkleTree: Total siblings does not correctly correspond to total leaves." + ); + + bytes32 computedRoot = _leaf; + + for (uint256 i = 0; i < _siblings.length; i++) { + if ((_index & 1) == 1) { + computedRoot = keccak256(abi.encodePacked(_siblings[i], computedRoot)); + } else { + computedRoot = keccak256(abi.encodePacked(computedRoot, _siblings[i])); + } + + _index >>= 1; + } + + return _root == computedRoot; + } + + /********************* + * Private Functions * + *********************/ + + /** + * Calculates the integer ceiling of the log base 2 of an input. + * @param _in Unsigned input to calculate the log. + * @return ceil(log_base_2(_in)) + */ + function _ceilLog2(uint256 _in) private pure returns (uint256) { + require(_in > 0, "Lib_MerkleTree: Cannot compute ceil(log_2) of 0."); + + if (_in == 1) { + return 0; + } + + // Find the highest set bit (will be floor(log_2)). + // Borrowed with <3 from https://github.com/ethereum/solidity-examples + uint256 val = _in; + uint256 highest = 0; + for (uint256 i = 128; i >= 1; i >>= 1) { + if (val & (((uint256(1) << i) - 1) << i) != 0) { + highest += i; + val >>= i; + } + } + + // Increment by one if this is not a perfect logarithm. + if ((uint256(1) << highest) != _in) { + highest += 1; + } + + return highest; + } +} diff --git a/packages/contracts/src/contract-artifacts.ts b/packages/contracts/src/contract-artifacts.ts new file mode 100644 index 0000000000000..00f1fdd4742a4 --- /dev/null +++ b/packages/contracts/src/contract-artifacts.ts @@ -0,0 +1,363 @@ + + /* eslint-disable @typescript-eslint/no-var-requires, no-empty */ + /* + THIS FILE IS AUTOMATICALLY GENERATED. + DO NOT EDIT. + */ + + + let iL1ChugSplashDeployer + try { + iL1ChugSplashDeployer = require('../artifacts/contracts/chugsplash/interfaces/iL1ChugSplashDeployer.sol/iL1ChugSplashDeployer.json') + } catch {} + + + let L1ChugSplashProxy + try { + L1ChugSplashProxy = require('../artifacts/contracts/chugsplash/L1ChugSplashProxy.sol/L1ChugSplashProxy.json') + } catch {} + + + let AddressDictator + try { + AddressDictator = require('../artifacts/contracts/L1/deployment/AddressDictator.sol/AddressDictator.json') + } catch {} + + + let ChugSplashDictator + try { + ChugSplashDictator = require('../artifacts/contracts/L1/deployment/ChugSplashDictator.sol/ChugSplashDictator.json') + } catch {} + + + let IL1CrossDomainMessenger + try { + IL1CrossDomainMessenger = require('../artifacts/contracts/L1/messaging/IL1CrossDomainMessenger.sol/IL1CrossDomainMessenger.json') + } catch {} + + + let IL1ERC20Bridge + try { + IL1ERC20Bridge = require('../artifacts/contracts/L1/messaging/IL1ERC20Bridge.sol/IL1ERC20Bridge.json') + } catch {} + + + let IL1StandardBridge + try { + IL1StandardBridge = require('../artifacts/contracts/L1/messaging/IL1StandardBridge.sol/IL1StandardBridge.json') + } catch {} + + + let L1CrossDomainMessenger + try { + L1CrossDomainMessenger = require('../artifacts/contracts/L1/messaging/L1CrossDomainMessenger.sol/L1CrossDomainMessenger.json') + } catch {} + + + let L1StandardBridge + try { + L1StandardBridge = require('../artifacts/contracts/L1/messaging/L1StandardBridge.sol/L1StandardBridge.json') + } catch {} + + + let CanonicalTransactionChain + try { + CanonicalTransactionChain = require('../artifacts/contracts/L1/rollup/CanonicalTransactionChain.sol/CanonicalTransactionChain.json') + } catch {} + + + let ChainStorageContainer + try { + ChainStorageContainer = require('../artifacts/contracts/L1/rollup/ChainStorageContainer.sol/ChainStorageContainer.json') + } catch {} + + + let ICanonicalTransactionChain + try { + ICanonicalTransactionChain = require('../artifacts/contracts/L1/rollup/ICanonicalTransactionChain.sol/ICanonicalTransactionChain.json') + } catch {} + + + let IChainStorageContainer + try { + IChainStorageContainer = require('../artifacts/contracts/L1/rollup/IChainStorageContainer.sol/IChainStorageContainer.json') + } catch {} + + + let IStateCommitmentChain + try { + IStateCommitmentChain = require('../artifacts/contracts/L1/rollup/IStateCommitmentChain.sol/IStateCommitmentChain.json') + } catch {} + + + let StateCommitmentChain + try { + StateCommitmentChain = require('../artifacts/contracts/L1/rollup/StateCommitmentChain.sol/StateCommitmentChain.json') + } catch {} + + + let BondManager + try { + BondManager = require('../artifacts/contracts/L1/verification/BondManager.sol/BondManager.json') + } catch {} + + + let IBondManager + try { + IBondManager = require('../artifacts/contracts/L1/verification/IBondManager.sol/IBondManager.json') + } catch {} + + + let IL2CrossDomainMessenger + try { + IL2CrossDomainMessenger = require('../artifacts/contracts/L2/messaging/IL2CrossDomainMessenger.sol/IL2CrossDomainMessenger.json') + } catch {} + + + let IL2ERC20Bridge + try { + IL2ERC20Bridge = require('../artifacts/contracts/L2/messaging/IL2ERC20Bridge.sol/IL2ERC20Bridge.json') + } catch {} + + + let L2CrossDomainMessenger + try { + L2CrossDomainMessenger = require('../artifacts/contracts/L2/messaging/L2CrossDomainMessenger.sol/L2CrossDomainMessenger.json') + } catch {} + + + let L2StandardBridge + try { + L2StandardBridge = require('../artifacts/contracts/L2/messaging/L2StandardBridge.sol/L2StandardBridge.json') + } catch {} + + + let L2StandardTokenFactory + try { + L2StandardTokenFactory = require('../artifacts/contracts/L2/messaging/L2StandardTokenFactory.sol/L2StandardTokenFactory.json') + } catch {} + + + let iOVM_L1BlockNumber + try { + iOVM_L1BlockNumber = require('../artifacts/contracts/L2/predeploys/iOVM_L1BlockNumber.sol/iOVM_L1BlockNumber.json') + } catch {} + + + let iOVM_L2ToL1MessagePasser + try { + iOVM_L2ToL1MessagePasser = require('../artifacts/contracts/L2/predeploys/iOVM_L2ToL1MessagePasser.sol/iOVM_L2ToL1MessagePasser.json') + } catch {} + + + let OVM_DeployerWhitelist + try { + OVM_DeployerWhitelist = require('../artifacts/contracts/L2/predeploys/OVM_DeployerWhitelist.sol/OVM_DeployerWhitelist.json') + } catch {} + + + let OVM_ETH + try { + OVM_ETH = require('../artifacts/contracts/L2/predeploys/OVM_ETH.sol/OVM_ETH.json') + } catch {} + + + let OVM_GasPriceOracle + try { + OVM_GasPriceOracle = require('../artifacts/contracts/L2/predeploys/OVM_GasPriceOracle.sol/OVM_GasPriceOracle.json') + } catch {} + + + let OVM_L2ToL1MessagePasser + try { + OVM_L2ToL1MessagePasser = require('../artifacts/contracts/L2/predeploys/OVM_L2ToL1MessagePasser.sol/OVM_L2ToL1MessagePasser.json') + } catch {} + + + let OVM_SequencerFeeVault + try { + OVM_SequencerFeeVault = require('../artifacts/contracts/L2/predeploys/OVM_SequencerFeeVault.sol/OVM_SequencerFeeVault.json') + } catch {} + + + let WETH9 + try { + WETH9 = require('../artifacts/contracts/L2/predeploys/WETH9.sol/WETH9.json') + } catch {} + + + let CrossDomainEnabled + try { + CrossDomainEnabled = require('../artifacts/contracts/libraries/bridge/CrossDomainEnabled.sol/CrossDomainEnabled.json') + } catch {} + + + let ICrossDomainMessenger + try { + ICrossDomainMessenger = require('../artifacts/contracts/libraries/bridge/ICrossDomainMessenger.sol/ICrossDomainMessenger.json') + } catch {} + + + let Lib_CrossDomainUtils + try { + Lib_CrossDomainUtils = require('../artifacts/contracts/libraries/bridge/Lib_CrossDomainUtils.sol/Lib_CrossDomainUtils.json') + } catch {} + + + let Lib_OVMCodec + try { + Lib_OVMCodec = require('../artifacts/contracts/libraries/codec/Lib_OVMCodec.sol/Lib_OVMCodec.json') + } catch {} + + + let Lib_DefaultValues + try { + Lib_DefaultValues = require('../artifacts/contracts/libraries/constants/Lib_DefaultValues.sol/Lib_DefaultValues.json') + } catch {} + + + let Lib_PredeployAddresses + try { + Lib_PredeployAddresses = require('../artifacts/contracts/libraries/constants/Lib_PredeployAddresses.sol/Lib_PredeployAddresses.json') + } catch {} + + + let Lib_AddressManager + try { + Lib_AddressManager = require('../artifacts/contracts/libraries/resolver/Lib_AddressManager.sol/Lib_AddressManager.json') + } catch {} + + + let Lib_AddressResolver + try { + Lib_AddressResolver = require('../artifacts/contracts/libraries/resolver/Lib_AddressResolver.sol/Lib_AddressResolver.json') + } catch {} + + + let Lib_ResolvedDelegateProxy + try { + Lib_ResolvedDelegateProxy = require('../artifacts/contracts/libraries/resolver/Lib_ResolvedDelegateProxy.sol/Lib_ResolvedDelegateProxy.json') + } catch {} + + + let Lib_RLPReader + try { + Lib_RLPReader = require('../artifacts/contracts/libraries/rlp/Lib_RLPReader.sol/Lib_RLPReader.json') + } catch {} + + + let Lib_RLPWriter + try { + Lib_RLPWriter = require('../artifacts/contracts/libraries/rlp/Lib_RLPWriter.sol/Lib_RLPWriter.json') + } catch {} + + + let Lib_MerkleTrie + try { + Lib_MerkleTrie = require('../artifacts/contracts/libraries/trie/Lib_MerkleTrie.sol/Lib_MerkleTrie.json') + } catch {} + + + let Lib_SecureMerkleTrie + try { + Lib_SecureMerkleTrie = require('../artifacts/contracts/libraries/trie/Lib_SecureMerkleTrie.sol/Lib_SecureMerkleTrie.json') + } catch {} + + + let Lib_Buffer + try { + Lib_Buffer = require('../artifacts/contracts/libraries/utils/Lib_Buffer.sol/Lib_Buffer.json') + } catch {} + + + let Lib_Bytes32Utils + try { + Lib_Bytes32Utils = require('../artifacts/contracts/libraries/utils/Lib_Bytes32Utils.sol/Lib_Bytes32Utils.json') + } catch {} + + + let Lib_BytesUtils + try { + Lib_BytesUtils = require('../artifacts/contracts/libraries/utils/Lib_BytesUtils.sol/Lib_BytesUtils.json') + } catch {} + + + let Lib_MerkleTree + try { + Lib_MerkleTree = require('../artifacts/contracts/libraries/utils/Lib_MerkleTree.sol/Lib_MerkleTree.json') + } catch {} + + + let AddressAliasHelper + try { + AddressAliasHelper = require('../artifacts/contracts/standards/AddressAliasHelper.sol/AddressAliasHelper.json') + } catch {} + + + let IL2StandardERC20 + try { + IL2StandardERC20 = require('../artifacts/contracts/standards/IL2StandardERC20.sol/IL2StandardERC20.json') + } catch {} + + + let L2StandardERC20 + try { + L2StandardERC20 = require('../artifacts/contracts/standards/L2StandardERC20.sol/L2StandardERC20.json') + } catch {} + + + export const getContractArtifact = (name: string): any => { + return { + iL1ChugSplashDeployer, +L1ChugSplashProxy, +AddressDictator, +ChugSplashDictator, +IL1CrossDomainMessenger, +IL1ERC20Bridge, +IL1StandardBridge, +L1CrossDomainMessenger, +L1StandardBridge, +CanonicalTransactionChain, +ChainStorageContainer, +ICanonicalTransactionChain, +IChainStorageContainer, +IStateCommitmentChain, +StateCommitmentChain, +BondManager, +IBondManager, +IL2CrossDomainMessenger, +IL2ERC20Bridge, +L2CrossDomainMessenger, +L2StandardBridge, +L2StandardTokenFactory, +iOVM_L1BlockNumber, +iOVM_L2ToL1MessagePasser, +OVM_DeployerWhitelist, +OVM_ETH, +OVM_GasPriceOracle, +OVM_L2ToL1MessagePasser, +OVM_SequencerFeeVault, +WETH9, +CrossDomainEnabled, +ICrossDomainMessenger, +Lib_CrossDomainUtils, +Lib_OVMCodec, +Lib_DefaultValues, +Lib_PredeployAddresses, +Lib_AddressManager, +Lib_AddressResolver, +Lib_ResolvedDelegateProxy, +Lib_RLPReader, +Lib_RLPWriter, +Lib_MerkleTrie, +Lib_SecureMerkleTrie, +Lib_Buffer, +Lib_Bytes32Utils, +Lib_BytesUtils, +Lib_MerkleTree, +AddressAliasHelper, +IL2StandardERC20, +L2StandardERC20 + }[name] + } + \ No newline at end of file diff --git a/packages/contracts/src/contract-deployed-artifacts.ts b/packages/contracts/src/contract-deployed-artifacts.ts new file mode 100644 index 0000000000000..1ac7b74a6142b --- /dev/null +++ b/packages/contracts/src/contract-deployed-artifacts.ts @@ -0,0 +1,62 @@ + + /* eslint-disable */ + /* + THIS FILE IS AUTOMATICALLY GENERATED. + DO NOT EDIT. + */ + const goerli__AddressDictator = { abi: [{"inputs":[{"internalType":"contract Lib_AddressManager","name":"_manager","type":"address"},{"internalType":"address","name":"_finalOwner","type":"address"},{"internalType":"string[]","name":"_names","type":"string[]"},{"internalType":"address[]","name":"_addresses","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"finalOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNamedAddresses","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"internalType":"struct AddressDictator.NamedAddress[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"returnOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"}], address: '0x406905414D6c250C186F4616EFA38D5fc0759437' } +const goerli__BondManager = { abi: [{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"_who","type":"address"}],"name":"isCollateralized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"libAddressManager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"resolve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}], address: '0xfC2ab6987C578218f99E85d61Dcf4814A26637Bd' } +const goerli__CanonicalTransactionChain = { abi: [{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"},{"internalType":"uint256","name":"_maxTransactionGasLimit","type":"uint256"},{"internalType":"uint256","name":"_l2GasDiscountDivisor","type":"uint256"},{"internalType":"uint256","name":"_enqueueGasCost","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"l2GasDiscountDivisor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"enqueueGasCost","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"enqueueL2GasPrepaid","type":"uint256"}],"name":"L2GasParamsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_startingQueueIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_numQueueElements","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_totalElements","type":"uint256"}],"name":"QueueBatchAppended","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_startingQueueIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_numQueueElements","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_totalElements","type":"uint256"}],"name":"SequencerBatchAppended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_batchIndex","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_batchRoot","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_batchSize","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_prevTotalElements","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"TransactionBatchAppended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_l1TxOrigin","type":"address"},{"indexed":true,"internalType":"address","name":"_target","type":"address"},{"indexed":false,"internalType":"uint256","name":"_gasLimit","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"},{"indexed":true,"internalType":"uint256","name":"_queueIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"TransactionEnqueued","type":"event"},{"inputs":[],"name":"MAX_ROLLUP_TX_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_ROLLUP_TX_GAS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"appendSequencerBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"batches","outputs":[{"internalType":"contract IChainStorageContainer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"uint256","name":"_gasLimit","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"enqueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enqueueGasCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enqueueL2GasPrepaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastBlockNumber","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastTimestamp","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNextQueueIndex","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumPendingQueueElements","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getQueueElement","outputs":[{"components":[{"internalType":"bytes32","name":"transactionHash","type":"bytes32"},{"internalType":"uint40","name":"timestamp","type":"uint40"},{"internalType":"uint40","name":"blockNumber","type":"uint40"}],"internalType":"struct Lib_OVMCodec.QueueElement","name":"_element","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getQueueLength","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalBatches","outputs":[{"internalType":"uint256","name":"_totalBatches","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalElements","outputs":[{"internalType":"uint256","name":"_totalElements","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2GasDiscountDivisor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"libAddressManager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTransactionGasLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"resolve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_l2GasDiscountDivisor","type":"uint256"},{"internalType":"uint256","name":"_enqueueGasCost","type":"uint256"}],"name":"setGasParams","outputs":[],"stateMutability":"nonpayable","type":"function"}], address: '0x607F755149cFEB3a14E1Dc3A4E2450Cde7dfb04D' } +const goerli__ChainStorageContainer_CTC_batches = { abi: [{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"},{"internalType":"string","name":"_owner","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"deleteElementsAfterInclusive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"deleteElementsAfterInclusive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"get","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGlobalMetadata","outputs":[{"internalType":"bytes27","name":"","type":"bytes27"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"length","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"libAddressManager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_object","type":"bytes32"},{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"push","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_object","type":"bytes32"}],"name":"push","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"resolve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"setGlobalMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"}], address: '0x4325Ac17c7fF5Afc0d05335dD30Db3D010455813' } +const goerli__ChainStorageContainer_SCC_batches = { abi: [{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"},{"internalType":"string","name":"_owner","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"deleteElementsAfterInclusive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"deleteElementsAfterInclusive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"get","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGlobalMetadata","outputs":[{"internalType":"bytes27","name":"","type":"bytes27"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"length","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"libAddressManager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_object","type":"bytes32"},{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"push","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_object","type":"bytes32"}],"name":"push","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"resolve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"setGlobalMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"}], address: '0x41eF5DaF4A7719bfe89A88BA3DD0DCFF5feCeD39' } +const goerli__ChugSplashDictator = { abi: [{"inputs":[{"internalType":"contract L1ChugSplashProxy","name":"_target","type":"address"},{"internalType":"address","name":"_finalOwner","type":"address"},{"internalType":"bytes32","name":"_codeHash","type":"bytes32"},{"internalType":"bytes32","name":"_messengerSlotKey","type":"bytes32"},{"internalType":"bytes32","name":"_messengerSlotVal","type":"bytes32"},{"internalType":"bytes32","name":"_bridgeSlotKey","type":"bytes32"},{"internalType":"bytes32","name":"_bridgeSlotVal","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"bridgeSlotKey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridgeSlotVal","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"codeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_code","type":"bytes"}],"name":"doActions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isUpgrading","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messengerSlotKey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messengerSlotVal","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"returnOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"target","outputs":[{"internalType":"contract L1ChugSplashProxy","name":"","type":"address"}],"stateMutability":"view","type":"function"}], address: '0x0e62FAf76a0239827f35f41478b521293e06195a' } +const goerli__L1StandardBridge_for_verification_only = { abi: [{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_l1Token","type":"address"},{"indexed":true,"internalType":"address","name":"_l2Token","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"ERC20DepositInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_l1Token","type":"address"},{"indexed":true,"internalType":"address","name":"_l2Token","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"ERC20WithdrawalFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"ETHDepositInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"ETHWithdrawalFinalized","type":"event"},{"inputs":[{"internalType":"address","name":"_l1Token","type":"address"},{"internalType":"address","name":"_l2Token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint32","name":"_l2Gas","type":"uint32"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"depositERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_l1Token","type":"address"},{"internalType":"address","name":"_l2Token","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint32","name":"_l2Gas","type":"uint32"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"depositERC20To","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_l2Gas","type":"uint32"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"depositETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint32","name":"_l2Gas","type":"uint32"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"depositETHTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"deposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"donateETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_l1Token","type":"address"},{"internalType":"address","name":"_l2Token","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"finalizeERC20Withdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"finalizeETHWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_l1messenger","type":"address"},{"internalType":"address","name":"_l2TokenBridge","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"l2TokenBridge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messenger","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}], address: '0x65DD71354923A51fC00DaE41A39F37eBB66549d4' } +const goerli__Lib_AddressManager = { abi: [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"_name","type":"string"},{"indexed":false,"internalType":"address","name":"_newAddress","type":"address"},{"indexed":false,"internalType":"address","name":"_oldAddress","type":"address"}],"name":"AddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"getAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"address","name":"_address","type":"address"}],"name":"setAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}], address: '0xa6f73589243a6A7a9023b1Fa0651b1d89c177111' } +const goerli__OVM_L1CrossDomainMessenger = { abi: [{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"msgHash","type":"bytes32"}],"name":"FailedRelayedMessage","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_xDomainCalldataHash","type":"bytes32"}],"name":"MessageAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_xDomainCalldataHash","type":"bytes32"}],"name":"MessageBlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"msgHash","type":"bytes32"}],"name":"RelayedMessage","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"messageNonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasLimit","type":"uint256"}],"name":"SentMessage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"bytes32","name":"_xDomainCalldataHash","type":"bytes32"}],"name":"allowMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_xDomainCalldataHash","type":"bytes32"}],"name":"blockMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"blockedMessages","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"libAddressManager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"address","name":"_sender","type":"address"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"uint256","name":"_messageNonce","type":"uint256"},{"components":[{"internalType":"bytes32","name":"stateRoot","type":"bytes32"},{"components":[{"internalType":"uint256","name":"batchIndex","type":"uint256"},{"internalType":"bytes32","name":"batchRoot","type":"bytes32"},{"internalType":"uint256","name":"batchSize","type":"uint256"},{"internalType":"uint256","name":"prevTotalElements","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct Lib_OVMCodec.ChainBatchHeader","name":"stateRootBatchHeader","type":"tuple"},{"components":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bytes32[]","name":"siblings","type":"bytes32[]"}],"internalType":"struct Lib_OVMCodec.ChainInclusionProof","name":"stateRootProof","type":"tuple"},{"internalType":"bytes","name":"stateTrieWitness","type":"bytes"},{"internalType":"bytes","name":"storageTrieWitness","type":"bytes"}],"internalType":"struct IL1CrossDomainMessenger.L2MessageInclusionProof","name":"_proof","type":"tuple"}],"name":"relayMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"relayedMessages","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"address","name":"_sender","type":"address"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"uint256","name":"_queueIndex","type":"uint256"},{"internalType":"uint32","name":"_oldGasLimit","type":"uint32"},{"internalType":"uint32","name":"_newGasLimit","type":"uint32"}],"name":"replayMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"resolve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"uint32","name":"_gasLimit","type":"uint32"}],"name":"sendMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"successfulMessages","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"xDomainMessageSender","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}], address: '0x2eB424e0930E93Cf250e488f6117a929714Bb928' } +const goerli__Proxy__OVM_L1CrossDomainMessenger = { abi: [{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"},{"internalType":"string","name":"_implementationName","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"stateMutability":"payable","type":"fallback"}], address: '0x5086d1eEF304eb5284A0f6720f79403b4e9bE294' } +const goerli__Proxy__OVM_L1StandardBridge = { abi: [{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"getImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_code","type":"bytes"}],"name":"setCode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"},{"internalType":"bytes32","name":"_value","type":"bytes32"}],"name":"setStorage","outputs":[],"stateMutability":"nonpayable","type":"function"}], address: '0x636Af16bf2f682dD3109e60102b8E1A089FedAa8' } +const goerli__StateCommitmentChain = { abi: [{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"},{"internalType":"uint256","name":"_fraudProofWindow","type":"uint256"},{"internalType":"uint256","name":"_sequencerPublishWindow","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_batchIndex","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_batchRoot","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_batchSize","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_prevTotalElements","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"StateBatchAppended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_batchIndex","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_batchRoot","type":"bytes32"}],"name":"StateBatchDeleted","type":"event"},{"inputs":[],"name":"FRAUD_PROOF_WINDOW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEQUENCER_PUBLISH_WINDOW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_batch","type":"bytes32[]"},{"internalType":"uint256","name":"_shouldStartAtElement","type":"uint256"}],"name":"appendStateBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"batches","outputs":[{"internalType":"contract IChainStorageContainer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"batchIndex","type":"uint256"},{"internalType":"bytes32","name":"batchRoot","type":"bytes32"},{"internalType":"uint256","name":"batchSize","type":"uint256"},{"internalType":"uint256","name":"prevTotalElements","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct Lib_OVMCodec.ChainBatchHeader","name":"_batchHeader","type":"tuple"}],"name":"deleteStateBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getLastSequencerTimestamp","outputs":[{"internalType":"uint256","name":"_lastSequencerTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalBatches","outputs":[{"internalType":"uint256","name":"_totalBatches","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalElements","outputs":[{"internalType":"uint256","name":"_totalElements","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"batchIndex","type":"uint256"},{"internalType":"bytes32","name":"batchRoot","type":"bytes32"},{"internalType":"uint256","name":"batchSize","type":"uint256"},{"internalType":"uint256","name":"prevTotalElements","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct Lib_OVMCodec.ChainBatchHeader","name":"_batchHeader","type":"tuple"}],"name":"insideFraudProofWindow","outputs":[{"internalType":"bool","name":"_inside","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"libAddressManager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"resolve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_element","type":"bytes32"},{"components":[{"internalType":"uint256","name":"batchIndex","type":"uint256"},{"internalType":"bytes32","name":"batchRoot","type":"bytes32"},{"internalType":"uint256","name":"batchSize","type":"uint256"},{"internalType":"uint256","name":"prevTotalElements","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct Lib_OVMCodec.ChainBatchHeader","name":"_batchHeader","type":"tuple"},{"components":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bytes32[]","name":"siblings","type":"bytes32[]"}],"internalType":"struct Lib_OVMCodec.ChainInclusionProof","name":"_proof","type":"tuple"}],"name":"verifyStateCommitment","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}], address: '0x9c945aC97Baf48cB784AbBB61399beB71aF7A378' } +const mainnet__AddressDictator = { abi: [{"inputs":[{"internalType":"contract Lib_AddressManager","name":"_manager","type":"address"},{"internalType":"address","name":"_finalOwner","type":"address"},{"internalType":"string[]","name":"_names","type":"string[]"},{"internalType":"address[]","name":"_addresses","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"finalOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNamedAddresses","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"internalType":"struct AddressDictator.NamedAddress[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"returnOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"}], address: '0x7a74f7934a233e10E8757264132B2E4EbccF5098' } +const mainnet__BondManager = { abi: [{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"_who","type":"address"}],"name":"isCollateralized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"libAddressManager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"resolve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}], address: '0xcd626E1328b41fCF24737F137BcD4CE0c32bc8d1' } +const mainnet__CanonicalTransactionChain = { abi: [{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"},{"internalType":"uint256","name":"_maxTransactionGasLimit","type":"uint256"},{"internalType":"uint256","name":"_l2GasDiscountDivisor","type":"uint256"},{"internalType":"uint256","name":"_enqueueGasCost","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"l2GasDiscountDivisor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"enqueueGasCost","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"enqueueL2GasPrepaid","type":"uint256"}],"name":"L2GasParamsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_startingQueueIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_numQueueElements","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_totalElements","type":"uint256"}],"name":"QueueBatchAppended","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_startingQueueIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_numQueueElements","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_totalElements","type":"uint256"}],"name":"SequencerBatchAppended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_batchIndex","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_batchRoot","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_batchSize","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_prevTotalElements","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"TransactionBatchAppended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_l1TxOrigin","type":"address"},{"indexed":true,"internalType":"address","name":"_target","type":"address"},{"indexed":false,"internalType":"uint256","name":"_gasLimit","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"},{"indexed":true,"internalType":"uint256","name":"_queueIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"TransactionEnqueued","type":"event"},{"inputs":[],"name":"MAX_ROLLUP_TX_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_ROLLUP_TX_GAS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"appendSequencerBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"batches","outputs":[{"internalType":"contract IChainStorageContainer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"uint256","name":"_gasLimit","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"enqueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enqueueGasCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enqueueL2GasPrepaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastBlockNumber","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastTimestamp","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNextQueueIndex","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumPendingQueueElements","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getQueueElement","outputs":[{"components":[{"internalType":"bytes32","name":"transactionHash","type":"bytes32"},{"internalType":"uint40","name":"timestamp","type":"uint40"},{"internalType":"uint40","name":"blockNumber","type":"uint40"}],"internalType":"struct Lib_OVMCodec.QueueElement","name":"_element","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getQueueLength","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalBatches","outputs":[{"internalType":"uint256","name":"_totalBatches","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalElements","outputs":[{"internalType":"uint256","name":"_totalElements","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2GasDiscountDivisor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"libAddressManager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTransactionGasLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"resolve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_l2GasDiscountDivisor","type":"uint256"},{"internalType":"uint256","name":"_enqueueGasCost","type":"uint256"}],"name":"setGasParams","outputs":[],"stateMutability":"nonpayable","type":"function"}], address: '0x5E4e65926BA27467555EB562121fac00D24E9dD2' } +const mainnet__ChainStorageContainer_CTC_batches = { abi: [{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"},{"internalType":"string","name":"_owner","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"deleteElementsAfterInclusive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"deleteElementsAfterInclusive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"get","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGlobalMetadata","outputs":[{"internalType":"bytes27","name":"","type":"bytes27"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"length","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"libAddressManager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_object","type":"bytes32"},{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"push","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_object","type":"bytes32"}],"name":"push","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"resolve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"setGlobalMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"}], address: '0xD16463EF9b0338CE3D73309028ef1714D220c024' } +const mainnet__ChainStorageContainer_SCC_batches = { abi: [{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"},{"internalType":"string","name":"_owner","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"deleteElementsAfterInclusive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"deleteElementsAfterInclusive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"get","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGlobalMetadata","outputs":[{"internalType":"bytes27","name":"","type":"bytes27"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"length","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"libAddressManager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_object","type":"bytes32"},{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"push","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_object","type":"bytes32"}],"name":"push","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"resolve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes27","name":"_globalMetadata","type":"bytes27"}],"name":"setGlobalMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"}], address: '0xb0ddFf09c4019e31960de11bD845E836078E8EbE' } +const mainnet__ChugSplashDictator = { abi: [{"inputs":[{"internalType":"contract L1ChugSplashProxy","name":"_target","type":"address"},{"internalType":"address","name":"_finalOwner","type":"address"},{"internalType":"bytes32","name":"_codeHash","type":"bytes32"},{"internalType":"bytes32","name":"_messengerSlotKey","type":"bytes32"},{"internalType":"bytes32","name":"_messengerSlotVal","type":"bytes32"},{"internalType":"bytes32","name":"_bridgeSlotKey","type":"bytes32"},{"internalType":"bytes32","name":"_bridgeSlotVal","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"bridgeSlotKey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridgeSlotVal","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"codeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_code","type":"bytes"}],"name":"doActions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isUpgrading","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messengerSlotKey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messengerSlotVal","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"returnOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"target","outputs":[{"internalType":"contract L1ChugSplashProxy","name":"","type":"address"}],"stateMutability":"view","type":"function"}], address: '0xD86065136E3ab1e3FCBbf47B59404c08A431051A' } +const mainnet__L1StandardBridge_for_verification_only = { abi: [{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_l1Token","type":"address"},{"indexed":true,"internalType":"address","name":"_l2Token","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"ERC20DepositInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_l1Token","type":"address"},{"indexed":true,"internalType":"address","name":"_l2Token","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"ERC20WithdrawalFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"ETHDepositInitiated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"ETHWithdrawalFinalized","type":"event"},{"inputs":[{"internalType":"address","name":"_l1Token","type":"address"},{"internalType":"address","name":"_l2Token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint32","name":"_l2Gas","type":"uint32"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"depositERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_l1Token","type":"address"},{"internalType":"address","name":"_l2Token","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint32","name":"_l2Gas","type":"uint32"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"depositERC20To","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_l2Gas","type":"uint32"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"depositETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint32","name":"_l2Gas","type":"uint32"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"depositETHTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"deposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"donateETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_l1Token","type":"address"},{"internalType":"address","name":"_l2Token","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"finalizeERC20Withdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"finalizeETHWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_l1messenger","type":"address"},{"internalType":"address","name":"_l2TokenBridge","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"l2TokenBridge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messenger","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}], address: '0x29Ea454F8f2750e345E52e302A0c09f1A5215AC7' } +const mainnet__Lib_AddressManager = { abi: [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"_name","type":"string"},{"indexed":false,"internalType":"address","name":"_newAddress","type":"address"},{"indexed":false,"internalType":"address","name":"_oldAddress","type":"address"}],"name":"AddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"getAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"address","name":"_address","type":"address"}],"name":"setAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}], address: '0xdE1FCfB0851916CA5101820A69b13a4E276bd81F' } +const mainnet__OVM_L1CrossDomainMessenger = { abi: [{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"msgHash","type":"bytes32"}],"name":"FailedRelayedMessage","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_xDomainCalldataHash","type":"bytes32"}],"name":"MessageAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_xDomainCalldataHash","type":"bytes32"}],"name":"MessageBlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"msgHash","type":"bytes32"}],"name":"RelayedMessage","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"messageNonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasLimit","type":"uint256"}],"name":"SentMessage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"bytes32","name":"_xDomainCalldataHash","type":"bytes32"}],"name":"allowMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_xDomainCalldataHash","type":"bytes32"}],"name":"blockMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"blockedMessages","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"libAddressManager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"address","name":"_sender","type":"address"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"uint256","name":"_messageNonce","type":"uint256"},{"components":[{"internalType":"bytes32","name":"stateRoot","type":"bytes32"},{"components":[{"internalType":"uint256","name":"batchIndex","type":"uint256"},{"internalType":"bytes32","name":"batchRoot","type":"bytes32"},{"internalType":"uint256","name":"batchSize","type":"uint256"},{"internalType":"uint256","name":"prevTotalElements","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct Lib_OVMCodec.ChainBatchHeader","name":"stateRootBatchHeader","type":"tuple"},{"components":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bytes32[]","name":"siblings","type":"bytes32[]"}],"internalType":"struct Lib_OVMCodec.ChainInclusionProof","name":"stateRootProof","type":"tuple"},{"internalType":"bytes","name":"stateTrieWitness","type":"bytes"},{"internalType":"bytes","name":"storageTrieWitness","type":"bytes"}],"internalType":"struct IL1CrossDomainMessenger.L2MessageInclusionProof","name":"_proof","type":"tuple"}],"name":"relayMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"relayedMessages","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"address","name":"_sender","type":"address"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"uint256","name":"_queueIndex","type":"uint256"},{"internalType":"uint32","name":"_oldGasLimit","type":"uint32"},{"internalType":"uint32","name":"_newGasLimit","type":"uint32"}],"name":"replayMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"resolve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"uint32","name":"_gasLimit","type":"uint32"}],"name":"sendMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"successfulMessages","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"xDomainMessageSender","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}], address: '0xd9166833FF12A5F900ccfBf2c8B62a90F1Ca1FD5' } +const mainnet__Proxy__OVM_L1CrossDomainMessenger = { abi: [{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"},{"internalType":"string","name":"_implementationName","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"stateMutability":"payable","type":"fallback"}], address: '0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1' } +const mainnet__Proxy__OVM_L1StandardBridge = { abi: [{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"getImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_code","type":"bytes"}],"name":"setCode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"},{"internalType":"bytes32","name":"_value","type":"bytes32"}],"name":"setStorage","outputs":[],"stateMutability":"nonpayable","type":"function"}], address: '0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1' } +const mainnet__StateCommitmentChain = { abi: [{"inputs":[{"internalType":"address","name":"_libAddressManager","type":"address"},{"internalType":"uint256","name":"_fraudProofWindow","type":"uint256"},{"internalType":"uint256","name":"_sequencerPublishWindow","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_batchIndex","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_batchRoot","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_batchSize","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_prevTotalElements","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"StateBatchAppended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_batchIndex","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_batchRoot","type":"bytes32"}],"name":"StateBatchDeleted","type":"event"},{"inputs":[],"name":"FRAUD_PROOF_WINDOW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEQUENCER_PUBLISH_WINDOW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_batch","type":"bytes32[]"},{"internalType":"uint256","name":"_shouldStartAtElement","type":"uint256"}],"name":"appendStateBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"batches","outputs":[{"internalType":"contract IChainStorageContainer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"batchIndex","type":"uint256"},{"internalType":"bytes32","name":"batchRoot","type":"bytes32"},{"internalType":"uint256","name":"batchSize","type":"uint256"},{"internalType":"uint256","name":"prevTotalElements","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct Lib_OVMCodec.ChainBatchHeader","name":"_batchHeader","type":"tuple"}],"name":"deleteStateBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getLastSequencerTimestamp","outputs":[{"internalType":"uint256","name":"_lastSequencerTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalBatches","outputs":[{"internalType":"uint256","name":"_totalBatches","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalElements","outputs":[{"internalType":"uint256","name":"_totalElements","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"batchIndex","type":"uint256"},{"internalType":"bytes32","name":"batchRoot","type":"bytes32"},{"internalType":"uint256","name":"batchSize","type":"uint256"},{"internalType":"uint256","name":"prevTotalElements","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct Lib_OVMCodec.ChainBatchHeader","name":"_batchHeader","type":"tuple"}],"name":"insideFraudProofWindow","outputs":[{"internalType":"bool","name":"_inside","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"libAddressManager","outputs":[{"internalType":"contract Lib_AddressManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"resolve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_element","type":"bytes32"},{"components":[{"internalType":"uint256","name":"batchIndex","type":"uint256"},{"internalType":"bytes32","name":"batchRoot","type":"bytes32"},{"internalType":"uint256","name":"batchSize","type":"uint256"},{"internalType":"uint256","name":"prevTotalElements","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct Lib_OVMCodec.ChainBatchHeader","name":"_batchHeader","type":"tuple"},{"components":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bytes32[]","name":"siblings","type":"bytes32[]"}],"internalType":"struct Lib_OVMCodec.ChainInclusionProof","name":"_proof","type":"tuple"}],"name":"verifyStateCommitment","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}], address: '0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19' } +const mainnet__TeleportrDeposit = { abi: [{"inputs":[{"internalType":"uint256","name":"_minDepositAmount","type":"uint256"},{"internalType":"uint256","name":"_maxDepositAmount","type":"uint256"},{"internalType":"uint256","name":"_maxBalance","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"BalanceWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"depositId","type":"uint256"},{"indexed":true,"internalType":"address","name":"emitter","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EtherReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"MaxBalanceSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"previousAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"MaxDepositAmountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"previousAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"MinDepositAmountSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"maxBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDepositAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minDepositAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxDepositAmount","type":"uint256"}],"name":"setMaxAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxBalance","type":"uint256"}],"name":"setMaxBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minDepositAmount","type":"uint256"}],"name":"setMinAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}], address: '0x52ec2F3d7C5977A8E558C8D9C6000B615098E8fC' } + + export const getDeployedContractArtifact = (name: string, network: string): any => { + return { + goerli__AddressDictator, +goerli__BondManager, +goerli__CanonicalTransactionChain, +goerli__ChainStorageContainer_CTC_batches, +goerli__ChainStorageContainer_SCC_batches, +goerli__ChugSplashDictator, +goerli__L1StandardBridge_for_verification_only, +goerli__Lib_AddressManager, +goerli__OVM_L1CrossDomainMessenger, +goerli__Proxy__OVM_L1CrossDomainMessenger, +goerli__Proxy__OVM_L1StandardBridge, +goerli__StateCommitmentChain, +mainnet__AddressDictator, +mainnet__BondManager, +mainnet__CanonicalTransactionChain, +mainnet__ChainStorageContainer_CTC_batches, +mainnet__ChainStorageContainer_SCC_batches, +mainnet__ChugSplashDictator, +mainnet__L1StandardBridge_for_verification_only, +mainnet__Lib_AddressManager, +mainnet__OVM_L1CrossDomainMessenger, +mainnet__Proxy__OVM_L1CrossDomainMessenger, +mainnet__Proxy__OVM_L1StandardBridge, +mainnet__StateCommitmentChain, +mainnet__TeleportrDeposit + }[(network + '__' + name).replace(/-/g, '_')] + } + \ No newline at end of file diff --git a/packages/contracts/standards/AddressAliasHelper.sol b/packages/contracts/standards/AddressAliasHelper.sol new file mode 100644 index 0000000000000..6a4edefae3e9f --- /dev/null +++ b/packages/contracts/standards/AddressAliasHelper.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 + +/* + * Copyright 2019-2021, Offchain Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +pragma solidity ^0.8.7; + +library AddressAliasHelper { + uint160 constant offset = uint160(0x1111000000000000000000000000000000001111); + + /// @notice Utility function that converts the address in the L1 that submitted a tx to + /// the inbox to the msg.sender viewed in the L2 + /// @param l1Address the address in the L1 that triggered the tx to L2 + /// @return l2Address L2 address as viewed in msg.sender + function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) { + unchecked { + l2Address = address(uint160(l1Address) + offset); + } + } + + /// @notice Utility function that converts the msg.sender viewed in the L2 to the + /// address in the L1 that submitted a tx to the inbox + /// @param l2Address L2 address as viewed in msg.sender + /// @return l1Address the address in the L1 that triggered the tx to L2 + function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) { + unchecked { + l1Address = address(uint160(l2Address) - offset); + } + } +} diff --git a/packages/contracts/standards/IL2StandardERC20.sol b/packages/contracts/standards/IL2StandardERC20.sol new file mode 100644 index 0000000000000..efa20278559e8 --- /dev/null +++ b/packages/contracts/standards/IL2StandardERC20.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; + +interface IL2StandardERC20 is IERC20, IERC165 { + function l1Token() external returns (address); + + function mint(address _to, uint256 _amount) external; + + function burn(address _from, uint256 _amount) external; + + event Mint(address indexed _account, uint256 _amount); + event Burn(address indexed _account, uint256 _amount); +} diff --git a/packages/contracts/standards/L2StandardERC20.sol b/packages/contracts/standards/L2StandardERC20.sol new file mode 100644 index 0000000000000..755e526758319 --- /dev/null +++ b/packages/contracts/standards/L2StandardERC20.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "./IL2StandardERC20.sol"; + +contract L2StandardERC20 is IL2StandardERC20, ERC20 { + address public l1Token; + address public l2Bridge; + + /** + * @param _l2Bridge Address of the L2 standard bridge. + * @param _l1Token Address of the corresponding L1 token. + * @param _name ERC20 name. + * @param _symbol ERC20 symbol. + */ + constructor( + address _l2Bridge, + address _l1Token, + string memory _name, + string memory _symbol + ) ERC20(_name, _symbol) { + l1Token = _l1Token; + l2Bridge = _l2Bridge; + } + + modifier onlyL2Bridge() { + require(msg.sender == l2Bridge, "Only L2 Bridge can mint and burn"); + _; + } + + // slither-disable-next-line external-function + function supportsInterface(bytes4 _interfaceId) public pure returns (bool) { + bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165 + bytes4 secondSupportedInterface = IL2StandardERC20.l1Token.selector ^ + IL2StandardERC20.mint.selector ^ + IL2StandardERC20.burn.selector; + return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface; + } + + // slither-disable-next-line external-function + function mint(address _to, uint256 _amount) public virtual onlyL2Bridge { + _mint(_to, _amount); + + emit Mint(_to, _amount); + } + + // slither-disable-next-line external-function + function burn(address _from, uint256 _amount) public virtual onlyL2Bridge { + _burn(_from, _amount); + + emit Burn(_from, _amount); + } +} From 85767b3365cc7b0d941cf92996503cbb09fc14db Mon Sep 17 00:00:00 2001 From: curryxbo Date: Fri, 7 Jul 2023 15:49:58 +0800 Subject: [PATCH 2/4] fix deployer --- op-chain-ops/deployer/deployer.go | 16 +--------------- op-chain-ops/genesis/layer_one.go | 8 ++++++-- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/op-chain-ops/deployer/deployer.go b/op-chain-ops/deployer/deployer.go index 3eeb7cca8333a..fa88d45bcb5da 100644 --- a/op-chain-ops/deployer/deployer.go +++ b/op-chain-ops/deployer/deployer.go @@ -3,9 +3,6 @@ package deployer import ( "context" "fmt" - "math/big" - "os" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" @@ -16,6 +13,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" + "math/big" ) // TestKey is the same test key that geth uses @@ -96,18 +94,6 @@ func Deploy(backend *backends.SimulatedBackend, constructors []Constructor, cb D return nil, err } - fmt.Println("_______________________________________________________-") - fmt.Println("_______________________________________________________-") - fmt.Println("_______________________________________________________-") - fmt.Println("_______________________________________________________-") - fmt.Println("_______________________________________________________-") - fmt.Println("_______________________________________________________-") - fmt.Println("_______________________________________________________-") - for _, deployment := range constructors { - fmt.Println("name", deployment.Name) - } - os.Exit(0) - opts.GasLimit = 15_000_000 ctx := context.Background() diff --git a/op-chain-ops/genesis/layer_one.go b/op-chain-ops/genesis/layer_one.go index d59e5b41fbecb..fac0ee9d2575b 100644 --- a/op-chain-ops/genesis/layer_one.go +++ b/op-chain-ops/genesis/layer_one.go @@ -86,6 +86,9 @@ func BuildL1DeveloperGenesis(config *DeployConfig) (*core.Genesis, error) { depsByName := make(map[string]deployer.Deployment) depsByAddr := make(map[common.Address]deployer.Deployment) for _, dep := range deployments { + // todo delete + fmt.Println("dep.Name", dep.Name) + fmt.Println("dep.Address.Hex()", dep.Address.Hex()) depsByName[dep.Name] = dep depsByAddr[dep.Address] = dep } @@ -99,8 +102,9 @@ func BuildL1DeveloperGenesis(config *DeployConfig) (*core.Genesis, error) { if err != nil { return nil, err } + // Initialize the OptimismPortal without being paused - data, err := portalABI.Pack("initialize", false) + data, err := portalABI.Pack("initialize", false, depsByName["L1CrossDomainMessenger"].Address) if err != nil { return nil, fmt.Errorf("cannot abi encode initialize for OptimismPortal: %w", err) } @@ -401,7 +405,7 @@ func l1Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, dep backend, deployment.Args[0].(common.Address), deployment.Args[1].(common.Address), - deployment.Args[2].(bool), + //deployment.Args[2].(bool), deployment.Args[3].(common.Address), ) case "L1CrossDomainMessenger": From ca2f3089152ee7ec12eba647b5f60edc31ea4603 Mon Sep 17 00:00:00 2001 From: curryxbo Date: Sun, 9 Jul 2023 22:28:12 +0800 Subject: [PATCH 3/4] fix potal --- packages/contracts-bedrock/contracts/L1/OptimismPortal.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol b/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol index 5193da4ab604e..07c76c305748b 100644 --- a/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol +++ b/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol @@ -108,7 +108,6 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { /// @notice Pass when onlyMessenger. modifier onlyMessenger(){ require(msg.sender == l1Messenger,"messenger contract unauthenticated"); - _; } /// @custom:semver 1.7.1 @@ -387,7 +386,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver { uint64 _gasLimit, bool _isCreation, bytes memory _data - ) public payable metered(_gasLimit) onlyMessenger{ + ) public metered(_gasLimit) onlyMessenger{ // Just to be safe, make sure that people specify address(0) as the target when doing // contract creations. if (_isCreation) { From d59fde86fe69c52d05f27484ea64a32fea685460 Mon Sep 17 00:00:00 2001 From: curryxbo Date: Mon, 10 Jul 2023 10:29:36 +0800 Subject: [PATCH 4/4] fix initialize --- op-chain-ops/genesis/layer_one.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/op-chain-ops/genesis/layer_one.go b/op-chain-ops/genesis/layer_one.go index fac0ee9d2575b..d38fabff96ab4 100644 --- a/op-chain-ops/genesis/layer_one.go +++ b/op-chain-ops/genesis/layer_one.go @@ -104,7 +104,7 @@ func BuildL1DeveloperGenesis(config *DeployConfig) (*core.Genesis, error) { } // Initialize the OptimismPortal without being paused - data, err := portalABI.Pack("initialize", false, depsByName["L1CrossDomainMessenger"].Address) + data, err := portalABI.Pack("initialize", false, config.L1CrossDomainMessengerProxy) if err != nil { return nil, fmt.Errorf("cannot abi encode initialize for OptimismPortal: %w", err) }