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 5426551f12c4a..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: "0x6101406040523480156200001257600080fd5b50604051620059c8380380620059c8833981016040819052620000359162000296565b6001608052600760a052600260c0526001600160a01b0380851660e052838116610120528116610100526200006a8262000074565b5050505062000302565b600054610100900460ff1615808015620000955750600054600160ff909116105b80620000c55750620000b230620001cb60201b62001c891760201c565b158015620000c5575060005460ff166001145b6200012e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000152576000805461ff0019166101001790555b603280546001600160a01b03191661dead1790556035805483151560ff1990911617905562000180620001da565b8015620001c7576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6001600160a01b03163b151590565b600054610100900460ff16620002475760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000125565b60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b6001600160a01b03811681146200029357600080fd5b50565b60008060008060808587031215620002ad57600080fd5b8451620002ba816200027d565b6020860151909450620002cd816200027d565b60408601519093508015158114620002e457600080fd5b6060860151909250620002f7816200027d565b939692955090935050565b60805160a05160c05160e051610100516101205161563762000391600039600081816102690152818161079d01526110a00152600081816104c801526123d701526000818161016a01528181610a0601528181610be701528181610ffc015281816113b60152818161162801526121c301526000610f6701526000610f3e01526000610f1501526156376000f3fe60806040526004361061012c5760003560e01c80638c3152e9116100a5578063cff0ab9611610074578063e965084c11610059578063e965084c14610417578063e9e05c42146104a3578063f0498750146104b657600080fd5b8063cff0ab9614610356578063d53a822f146103f757600080fd5b80638c3152e9146102a05780639bf62d82146102c0578063a14238e7146102ed578063a35d99df1461031d57600080fd5b80635c975abb116100fc578063724c184c116100e1578063724c184c146102575780638456cb591461028b5780638b4c40b01461015157600080fd5b80635c975abb1461020d5780636dbffb781461023757600080fd5b80621c2ff6146101585780633f4ba83a146101b65780634870496f146101cb57806354fd4d50146101eb57600080fd5b36610153576101513334620186a06000604051806020016040528060008152506104ea565b005b600080fd5b34801561016457600080fd5b5061018c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101c257600080fd5b50610151610785565b3480156101d757600080fd5b506101516101e6366004614be9565b6108a8565b3480156101f757600080fd5b50610200610f0e565b6040516101ad9190614d3f565b34801561021957600080fd5b506035546102279060ff1681565b60405190151581526020016101ad565b34801561024357600080fd5b50610227610252366004614d52565b610fb1565b34801561026357600080fd5b5061018c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561029757600080fd5b50610151611088565b3480156102ac57600080fd5b506101516102bb366004614d6b565b6111a8565b3480156102cc57600080fd5b5060325461018c9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102f957600080fd5b50610227610308366004614d52565b60336020526000908152604090205460ff1681565b34801561032957600080fd5b5061033d610338366004614db8565b611a83565b60405167ffffffffffffffff90911681526020016101ad565b34801561036257600080fd5b506001546103be906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101ad565b34801561040357600080fd5b50610151610412366004614de3565b611a9c565b34801561042357600080fd5b50610475610432366004614d52565b603460205260009081526040902080546001909101546fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041683565b604080519384526fffffffffffffffffffffffffffffffff92831660208501529116908201526060016101ad565b6101516104b1366004614dfe565b6104ea565b3480156104c257600080fd5b5061018c7f000000000000000000000000000000000000000000000000000000000000000081565b8260005a905083156105a15773ffffffffffffffffffffffffffffffffffffffff8716156105a157604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b6105ab8351611a83565b67ffffffffffffffff168567ffffffffffffffff16101561064e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4f7074696d69736d506f7274616c3a20676173206c696d697420746f6f20736d60448201527f616c6c00000000000000000000000000000000000000000000000000000000006064820152608401610598565b6201d4c0835111156106bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4f7074696d69736d506f7274616c3a206461746120746f6f206c6172676500006044820152606401610598565b333281146106dd575033731111000000000000000000000000000000001111015b600034888888886040516020016106f8959493929190614e77565b604051602081830303815290604052905060008973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fb3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32846040516107689190614d3f565b60405180910390a4505061077c8282611ca5565b50505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461084a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e20756e706175736500000000000000000000000000000000000000000000006064820152608401610598565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60355460ff1615610915576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610598565b3073ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff16036109d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610598565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610a62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a869190614efc565b519050610aa0610a9b36869003860186614f61565b611fd2565b8114610b2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610598565b6000610b398761202e565b6000818152603460209081526040918290208251606081018452815481526001909101546fffffffffffffffffffffffffffffffff8082169383018490527001000000000000000000000000000000009091041692810192909252919250901580610c6b5750805160408083015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015610c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c679190614efc565b5114155b610cf7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173682060448201527f68617320616c7265616479206265656e2070726f76656e0000000000000000006064820152608401610598565b60408051602081018490526000918101829052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083018190529250610dc09101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f0100000000000000000000000000000000000000000000000000000000000000602083015290610db6888a614fc7565b8a6040013561205e565b610e4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610598565b604080516060810182528581526fffffffffffffffffffffffffffffffff42811660208084019182528c831684860190815260008981526034835286812095518655925190518416700100000000000000000000000000000000029316929092176001909301929092558b830151908c0151925173ffffffffffffffffffffffffffffffffffffffff918216939091169186917f67a6208cfcc0801d50f6cbe764733f4fddf66ac0b04442061a8a8c0cb6b63f629190a4505050505050505050565b6060610f397f0000000000000000000000000000000000000000000000000000000000000000612082565b610f627f0000000000000000000000000000000000000000000000000000000000000000612082565b610f8b7f0000000000000000000000000000000000000000000000000000000000000000612082565b604051602001610f9d9392919061504b565b604051602081830303815290604052905090565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018290526000906110829073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae55790602401606060405180830381865afa158015611043573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110679190614efc565b602001516fffffffffffffffffffffffffffffffff166121bf565b92915050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461114d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4f7074696d69736d506f7274616c3a206f6e6c7920677561726469616e20636160448201527f6e207061757365000000000000000000000000000000000000000000000000006064820152608401610598565b603580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589060200161089e565b60355460ff1615611215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f7074696d69736d506f7274616c3a20706175736564000000000000000000006044820152606401610598565b60325473ffffffffffffffffffffffffffffffffffffffff1661dead146112be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610598565b60006112c98261202e565b60008181526034602090815260408083208151606081018352815481526001909101546fffffffffffffffffffffffffffffffff808216948301859052700100000000000000000000000000000000909104169181019190915292935090036113b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206e60448201527f6f74206265656e2070726f76656e2079657400000000000000000000000000006064820152608401610598565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663887862726040518163ffffffff1660e01b8152600401602060405180830381865afa15801561141f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144391906150c1565b81602001516fffffffffffffffffffffffffffffffff16101561150e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604b60248201527f4f7074696d69736d506f7274616c3a207769746864726177616c2074696d657360448201527f74616d70206c657373207468616e204c32204f7261636c65207374617274696e60648201527f672074696d657374616d70000000000000000000000000000000000000000000608482015260a401610598565b61152d81602001516fffffffffffffffffffffffffffffffff166121bf565b6115df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f4f7074696d69736d506f7274616c3a2070726f76656e2077697468647261776160448201527f6c2066696e616c697a6174696f6e20706572696f6420686173206e6f7420656c60648201527f6170736564000000000000000000000000000000000000000000000000000000608482015260a401610598565b60408181015190517fa25ae5570000000000000000000000000000000000000000000000000000000081526fffffffffffffffffffffffffffffffff90911660048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae55790602401606060405180830381865afa158015611684573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a89190614efc565b8251815191925014611762576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604960248201527f4f7074696d69736d506f7274616c3a206f757470757420726f6f742070726f7660448201527f656e206973206e6f74207468652073616d652061732063757272656e74206f7560648201527f7470757420726f6f740000000000000000000000000000000000000000000000608482015260a401610598565b61178181602001516fffffffffffffffffffffffffffffffff166121bf565b611833576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f7074696d69736d506f7274616c3a206f75747075742070726f706f73616c2060448201527f66696e616c697a6174696f6e20706572696f6420686173206e6f7420656c617060648201527f7365640000000000000000000000000000000000000000000000000000000000608482015260a401610598565b60008381526033602052604090205460ff16156118d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610598565b600083815260336020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055908601516032805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790558501516080860151606087015160a088015161197493929190612262565b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915084907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b906119d990841515815260200190565b60405180910390a2801580156119ef5750326001145b15611a7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4f7074696d69736d506f7274616c3a207769746864726177616c206661696c6560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610598565b5050505050565b6000611a90826010615109565b61108290615208615139565b600054610100900460ff1615808015611abc5750600054600160ff909116105b80611ad65750303b158015611ad6575060005460ff166001145b611b62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610598565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611bc057600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603280547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055603580548315157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055611c226122c0565b8015611c8557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600154600090611cdb907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643615165565b90506000611ce76123a3565b90506000816020015160ff16826000015163ffffffff16611d0891906151ab565b90508215611e3f57600154600090611d3f908390700100000000000000000000000000000000900467ffffffffffffffff16615213565b90506000836040015160ff1683611d569190615287565b600154611d769084906fffffffffffffffffffffffffffffffff16615287565b611d8091906151ab565b600154909150600090611dd190611daa9084906fffffffffffffffffffffffffffffffff16615343565b866060015163ffffffff168760a001516fffffffffffffffffffffffffffffffff16612469565b90506001861115611e0057611dfd611daa82876040015160ff1660018a611df89190615165565b612488565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b60018054869190601090611e72908490700100000000000000000000000000000000900467ffffffffffffffff16615139565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816000015163ffffffff16600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff161315611f55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f5265736f757263654d65746572696e673a2063616e6e6f7420627579206d6f7260448201527f6520676173207468616e20617661696c61626c6520676173206c696d697400006064820152608401610598565b600154600090611f81906fffffffffffffffffffffffffffffffff1667ffffffffffffffff88166153b7565b90506000611f9348633b9aca006124dd565b611f9d90836153f4565b905060005a611fac9088615165565b905080821115611fc857611fc8611fc38284615165565b6124f4565b5050505050505050565b60008160000151826020015183604001518460600151604051602001612011949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b80516020808301516040808501516060860151608087015160a08801519351600097612011979096959101615408565b60008061206a86612522565b905061207881868686612554565b9695505050505050565b6060816000036120c557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156120ef57806120d98161545f565b91506120e89050600a836153f4565b91506120c9565b60008167ffffffffffffffff81111561210a5761210a614a0f565b6040519080825280601f01601f191660200182016040528015612134576020820181803683370190505b5090505b84156121b757612149600183615165565b9150612156600a86615497565b6121619060306154ab565b60f81b818381518110612176576121766154c3565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506121b0600a866153f4565b9450612138565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f4daa2916040518163ffffffff1660e01b8152600401602060405180830381865afa15801561222c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225091906150c1565b61225a90836154ab565b421192915050565b6000806000612272866000612584565b9050806122a8576308c379a06000526020805278185361666543616c6c3a204e6f7420656e6f756768206761736058526064601cfd5b600080855160208701888b5af1979650505050505050565b600054610100900460ff16612357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610598565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663cc731b026040518163ffffffff1660e01b815260040160c060405180830381865afa158015612440573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124649190615517565b905090565b600061247e61247885856125a2565b836125b2565b90505b9392505050565b6000670de0b6b3a76400006124c96124a085836151ab565b6124b290670de0b6b3a7640000615213565b6124c485670de0b6b3a7640000615287565b6125c1565b6124d39086615287565b61247e91906151ab565b6000818310156124ed5781612481565b5090919050565b6000805a90505b825a6125079083615165565b101561251d576125168261545f565b91506124fb565b505050565b6060818051906020012060405160200161253e91815260200190565b6040516020818303038152906040529050919050565b600061257b846125658786866125f2565b8051602091820120825192909101919091201490565b95945050505050565b600080603f83619c4001026040850201603f5a021015949350505050565b6000818312156124ed5781612481565b60008183126124ed5781612481565b6000612481670de0b6b3a7640000836125d98661307a565b6125e39190615287565b6125ed91906151ab565b6132be565b6060600084511161265f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4d65726b6c65547269653a20656d707479206b657900000000000000000000006044820152606401610598565b600061266a846134fd565b90506000612677866135ec565b905060008460405160200161268e91815260200190565b60405160208183030381529060405290506000805b8451811015612ff15760008582815181106126c0576126c06154c3565b60200260200101519050845183111561275b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4d65726b6c65547269653a206b657920696e646578206578636565647320746f60448201527f74616c206b6579206c656e6774680000000000000000000000000000000000006064820152608401610598565b8260000361281457805180516020918201206040516127a99261278392910190815260200190565b604051602081830303815290604052858051602091820120825192909101919091201490565b61280f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d65726b6c65547269653a20696e76616c696420726f6f7420686173680000006044820152606401610598565b61296b565b8051516020116128ca578051805160209182012060405161283e9261278392910190815260200190565b61280f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4d65726b6c65547269653a20696e76616c6964206c6172676520696e7465726e60448201527f616c2068617368000000000000000000000000000000000000000000000000006064820152608401610598565b80518451602080870191909120825191909201201461296b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4d65726b6c65547269653a20696e76616c696420696e7465726e616c206e6f6460448201527f65206861736800000000000000000000000000000000000000000000000000006064820152608401610598565b612977601060016154ab565b81602001515103612b585784518303612af05760006129b382602001516010815181106129a6576129a66154c3565b602002602001015161364f565b90506000815111612a46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286272616e63682900000000006064820152608401610598565b60018751612a549190615165565b8314612ae2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286272616e6368290000000000006064820152608401610598565b965061248195505050505050565b6000858481518110612b0457612b046154c3565b602001015160f81c60f81b60f81c9050600082602001518260ff1681518110612b2f57612b2f6154c3565b60200260200101519050612b42816137af565b9550612b4f6001866154ab565b94505050612fde565b600281602001515103612f56576000612b70826137d4565b9050600081600081518110612b8757612b876154c3565b016020015160f81c90506000612b9e6002836155b6565b612ba99060026155d8565b90506000612bba848360ff166137f8565b90506000612bc88a896137f8565b90506000612bd6838361382e565b905080835114612c68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f4d65726b6c65547269653a20706174682072656d61696e646572206d7573742060448201527f736861726520616c6c206e6962626c65732077697468206b65790000000000006064820152608401610598565b60ff851660021480612c7d575060ff85166003145b15612e715780825114612d12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f4d65726b6c65547269653a206b65792072656d61696e646572206d757374206260448201527f65206964656e746963616c20746f20706174682072656d61696e6465720000006064820152608401610598565b6000612d2e88602001516001815181106129a6576129a66154c3565b90506000815111612dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f4d65726b6c65547269653a2076616c7565206c656e677468206d75737420626560448201527f2067726561746572207468616e207a65726f20286c65616629000000000000006064820152608401610598565b60018d51612dcf9190615165565b8914612e5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4d65726b6c65547269653a2076616c7565206e6f6465206d757374206265206c60448201527f617374206e6f646520696e2070726f6f6620286c6561662900000000000000006064820152608401610598565b9c506124819b505050505050505050505050565b60ff85161580612e84575060ff85166001145b15612ec357612eb08760200151600181518110612ea357612ea36154c3565b60200260200101516137af565b9950612ebc818a6154ab565b9850612f4b565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4d65726b6c65547269653a2072656365697665642061206e6f6465207769746860448201527f20616e20756e6b6e6f776e2070726566697800000000000000000000000000006064820152608401610598565b505050505050612fde565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4d65726b6c65547269653a20726563656976656420616e20756e70617273656160448201527f626c65206e6f64650000000000000000000000000000000000000000000000006064820152608401610598565b5080612fe98161545f565b9150506126a3565b506040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4d65726b6c65547269653a2072616e206f7574206f662070726f6f6620656c6560448201527f6d656e74730000000000000000000000000000000000000000000000000000006064820152608401610598565b60008082136130e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610598565b600060606130f2846138dd565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c182136132ef57506000919050565b680755bf798b4a1bf1e58212613361576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610598565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b805160609060008167ffffffffffffffff81111561351d5761351d614a0f565b60405190808252806020026020018201604052801561356257816020015b604080518082019091526060808252602082015281526020019060019003908161353b5790505b50905060005b828110156135e457604051806040016040528086838151811061358d5761358d6154c3565b602002602001015181526020016135bc8784815181106135af576135af6154c3565b60200260200101516139b3565b8152508282815181106135d1576135d16154c3565b6020908102919091010152600101613568565b509392505050565b606080604051905082518060011b603f8101601f1916830160405280835250602084016020830160005b83811015613644578060011b82018184015160001a8060041c8253600f811660018301535050600101613616565b509295945050505050565b6060600080600061365f856139c6565b91945092509050600081600181111561367a5761367a6155fb565b14613707576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206279746573206973206e6f7420612064617461206974656d000000000000006064820152608401610598565b61371182846154ab565b8551146137a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f524c505265616465723a2062797465732076616c756520636f6e7461696e732060448201527f616e20696e76616c69642072656d61696e6465720000000000000000000000006064820152608401610598565b61257b85602001518484614433565b606060208260000151106137cb576137c68261364f565b611082565b611082826144d4565b60606110826137f383602001516000815181106129a6576129a66154c3565b6135ec565b6060825182106138175750604080516020810190915260008152611082565b61248183838486516138299190615165565b6144ea565b60008060008351855110613843578351613846565b84515b90505b80821080156138cd5750838281518110613865576138656154c3565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168583815181106138a4576138a46154c3565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156135e457816001019150613849565b6000808211613948576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610598565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b60606110826139c1836146c2565b6147ab565b600080600080846000015111613a84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610598565b6020840151805160001a607f8111613aa957600060016000945094509450505061442c565b60b78111613cb7576000613abe608083615165565b905080876000015111613b79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604e60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20737472696e67206c656e6774682060648201527f2873686f727420737472696e6729000000000000000000000000000000000000608482015260a401610598565b6001838101517fff00000000000000000000000000000000000000000000000000000000000000169082141580613bf257507f80000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821610155b613ca4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a20696e76616c6964207072656669782c2073696e676c60448201527f652062797465203c203078383020617265206e6f74207072656669786564202860648201527f73686f727420737472696e672900000000000000000000000000000000000000608482015260a401610598565b506001955093506000925061442c915050565b60bf8111614005576000613ccc60b783615165565b905080876000015111613d87576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605160248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f6620737472696e67206c656e60648201527f67746820286c6f6e6720737472696e6729000000000000000000000000000000608482015260a401610598565b60018301517fff00000000000000000000000000000000000000000000000000000000000000166000819003613e65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e6720737472696e672900000000000000000000000000000000000000000000608482015260a401610598565b600184015160088302610100031c60378111613f29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f20737472696e6729000000000000000000000000000000000000000000000000608482015260a401610598565b613f3381846154ab565b895111613fe8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e6720737472696e67290000000000000000000000000000000000000000608482015260a401610598565b613ff38360016154ab565b975095506000945061442c9350505050565b60f781116140e657600061401a60c083615165565b9050808760000151116140d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e206c697374206c656e67746820287360648201527f686f7274206c6973742900000000000000000000000000000000000000000000608482015260a401610598565b60019550935084925061442c915050565b60006140f360f783615165565b9050808760000151116141ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206265203e207468616e206c656e677468206f66206c697374206c656e677460648201527f6820286c6f6e67206c6973742900000000000000000000000000000000000000608482015260a401610598565b60018301517fff0000000000000000000000000000000000000000000000000000000000000016600081900361428c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604860248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f74206e6f74206861766520616e79206c656164696e67207a65726f7320286c6f60648201527f6e67206c69737429000000000000000000000000000000000000000000000000608482015260a401610598565b600184015160088302610100031c60378111614350576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604660248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20353520627974657320286c6f6e6760648201527f206c697374290000000000000000000000000000000000000000000000000000608482015260a401610598565b61435a81846154ab565b89511161440f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620636f6e74656e74206d757360448201527f742062652067726561746572207468616e20746f74616c206c656e677468202860648201527f6c6f6e67206c6973742900000000000000000000000000000000000000000000608482015260a401610598565b61441a8360016154ab565b975095506001945061442c9350505050565b9193909250565b606060008267ffffffffffffffff81111561445057614450614a0f565b6040519080825280601f01601f19166020018201604052801561447a576020820181803683370190505b5090508260000361448c579050612481565b600061449885876154ab565b90506020820160005b858110156144b95782810151828201526020016144a1565b858111156144c8576000868301525b50919695505050505050565b6060611082826020015160008460000151614433565b60608182601f011015614559576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610598565b8282840110156145c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610598565b81830184511015614632576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610598565b60608215801561465157604051915060008252602082016040526146b9565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561468a578051835260209283019201614672565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b6040805180820190915260008082526020820152600082511161478d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f524c505265616465723a206c656e677468206f6620616e20524c50206974656d60448201527f206d7573742062652067726561746572207468616e207a65726f20746f20626560648201527f206465636f6461626c6500000000000000000000000000000000000000000000608482015260a401610598565b50604080518082019091528151815260209182019181019190915290565b606060008060006147bb856139c6565b9194509250905060018160018111156147d6576147d66155fb565b14614863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f524c505265616465723a206465636f646564206974656d207479706520666f7260448201527f206c697374206973206e6f742061206c697374206974656d00000000000000006064820152608401610598565b845161486f83856154ab565b146148fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f524c505265616465723a206c697374206974656d2068617320616e20696e766160448201527f6c696420646174612072656d61696e64657200000000000000000000000000006064820152608401610598565b6040805160208082526104208201909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816149155790505090506000845b8751811015614a03576000806149886040518060400160405280858d6000015161496c9190615165565b8152602001858d6020015161498191906154ab565b90526139c6565b5091509150604051806040016040528083836149a491906154ab565b8152602001848c602001516149b991906154ab565b8152508585815181106149ce576149ce6154c3565b60209081029190910101526149e46001856154ab565b93506149f081836154ab565b6149fa90846154ab565b92505050614942565b50815295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614a8557614a85614a0f565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114614ab157600080fd5b919050565b600082601f830112614ac757600080fd5b813567ffffffffffffffff811115614ae157614ae1614a0f565b614b1260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a3e565b818152846020838601011115614b2757600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614b5657600080fd5b60405160c0810167ffffffffffffffff8282108183111715614b7a57614b7a614a0f565b8160405282935084358352614b9160208601614a8d565b6020840152614ba260408601614a8d565b6040840152606085013560608401526080850135608084015260a0850135915080821115614bcf57600080fd5b50614bdc85828601614ab6565b60a0830152505092915050565b600080600080600085870360e0811215614c0257600080fd5b863567ffffffffffffffff80821115614c1a57600080fd5b614c268a838b01614b44565b97506020890135965060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc084011215614c5f57600080fd5b60408901955060c0890135925080831115614c7957600080fd5b828901925089601f840112614c8d57600080fd5b8235915080821115614c9e57600080fd5b508860208260051b8401011115614cb457600080fd5b959894975092955050506020019190565b60005b83811015614ce0578181015183820152602001614cc8565b83811115614cef576000848401525b50505050565b60008151808452614d0d816020860160208601614cc5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006124816020830184614cf5565b600060208284031215614d6457600080fd5b5035919050565b600060208284031215614d7d57600080fd5b813567ffffffffffffffff811115614d9457600080fd5b6121b784828501614b44565b803567ffffffffffffffff81168114614ab157600080fd5b600060208284031215614dca57600080fd5b61248182614da0565b80358015158114614ab157600080fd5b600060208284031215614df557600080fd5b61248182614dd3565b600080600080600060a08688031215614e1657600080fd5b614e1f86614a8d565b945060208601359350614e3460408701614da0565b9250614e4260608701614dd3565b9150608086013567ffffffffffffffff811115614e5e57600080fd5b614e6a88828901614ab6565b9150509295509295909350565b8581528460208201527fffffffffffffffff0000000000000000000000000000000000000000000000008460c01b16604082015282151560f81b604882015260008251614ecb816049850160208701614cc5565b919091016049019695505050505050565b80516fffffffffffffffffffffffffffffffff81168114614ab157600080fd5b600060608284031215614f0e57600080fd5b6040516060810181811067ffffffffffffffff82111715614f3157614f31614a0f565b60405282518152614f4460208401614edc565b6020820152614f5560408401614edc565b60408201529392505050565b600060808284031215614f7357600080fd5b6040516080810181811067ffffffffffffffff82111715614f9657614f96614a0f565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b600067ffffffffffffffff80841115614fe257614fe2614a0f565b8360051b6020614ff3818301614a3e565b86815291850191818101903684111561500b57600080fd5b865b8481101561503f578035868111156150255760008081fd5b61503136828b01614ab6565b84525091830191830161500d565b50979650505050505050565b6000845161505d818460208901614cc5565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551615099816001850160208a01614cc5565b600192019182015283516150b4816002840160208801614cc5565b0160020195945050505050565b6000602082840312156150d357600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600067ffffffffffffffff80831681851681830481118215151615615130576151306150da565b02949350505050565b600067ffffffffffffffff80831681851680830382111561515c5761515c6150da565b01949350505050565b600082821015615177576151776150da565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826151ba576151ba61517c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561520e5761520e6150da565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561524d5761524d6150da565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018313811615615281576152816150da565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156152c8576152c86150da565b7f80000000000000000000000000000000000000000000000000000000000000006000871286820588128184161615615303576153036150da565b6000871292508782058712848416161561531f5761531f6150da565b87850587128184161615615335576153356150da565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561537d5761537d6150da565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156153b1576153b16150da565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156153ef576153ef6150da565b500290565b6000826154035761540361517c565b500490565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a083015261545360c0830184614cf5565b98975050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615490576154906150da565b5060010190565b6000826154a6576154a661517c565b500690565b600082198211156154be576154be6150da565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b805163ffffffff81168114614ab157600080fd5b805160ff81168114614ab157600080fd5b600060c0828403121561552957600080fd5b60405160c0810181811067ffffffffffffffff8211171561554c5761554c614a0f565b604052615558836154f2565b815261556660208401615506565b602082015261557760408401615506565b6040820152615588606084016154f2565b6060820152615599608084016154f2565b60808201526155aa60a08401614edc565b60a08201529392505050565b600060ff8316806155c9576155c961517c565b8060ff84160691505092915050565b600060ff821660ff8416808210156155f2576155f26150da565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080f000a",
+ 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..fa88d45bcb5da 100644
--- a/op-chain-ops/deployer/deployer.go
+++ b/op-chain-ops/deployer/deployer.go
@@ -3,8 +3,6 @@ package deployer
import (
"context"
"fmt"
- "math/big"
-
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
@@ -15,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
diff --git a/op-chain-ops/genesis/layer_one.go b/op-chain-ops/genesis/layer_one.go
index d59e5b41fbecb..d38fabff96ab4 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, config.L1CrossDomainMessengerProxy)
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":
diff --git a/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol b/packages/contracts-bedrock/contracts/L1/OptimismPortal.sol
index 819cc59579f81..7b831f9e67258 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,34 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
_;
}
- /// @custom:semver 1.7.2
+ /// @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 withdrawals.
- /// @param _paused Sets the contract's pausability state.
+ /// @param _guardian Address that can pause deposits and withdrawals.
/// @param _config Address of the SystemConfig contract.
constructor(
L2OutputOracle _l2Oracle,
address _guardian,
- bool _paused,
+// bool _paused,
SystemConfig _config
) Semver(1, 7, 2) {
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 withdrawals.
@@ -379,7 +386,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
uint64 _gasLimit,
bool _isCreation,
bytes memory _data
- ) public payable metered(_gasLimit) {
+ ) public 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);
+ }
+}