diff --git a/op-bindings/artifacts.json b/op-bindings/artifacts.json index 4b37816cc972e..09135902f7ba9 100644 --- a/op-bindings/artifacts.json +++ b/op-bindings/artifacts.json @@ -44,6 +44,7 @@ "StorageSetter", "SuperchainConfig", "DataAvailabilityChallenge", + "L2ToL2CrossDomainMessenger", "CrossL2Inbox" ], "remote": [ @@ -146,4 +147,4 @@ "deploymentSalt": "0000000000000000000000000000000000000000000000000000000000000000" } ] -} +} \ No newline at end of file diff --git a/op-bindings/bindings/l2tol2crossdomainmessenger.go b/op-bindings/bindings/l2tol2crossdomainmessenger.go new file mode 100644 index 0000000000000..b30fa951f4a6f --- /dev/null +++ b/op-bindings/bindings/l2tol2crossdomainmessenger.go @@ -0,0 +1,811 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// L2ToL2CrossDomainMessengerMetaData contains all meta data concerning the L2ToL2CrossDomainMessenger contract. +var L2ToL2CrossDomainMessengerMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"CROSS_DOMAIN_MESSAGE_SENDER_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"CROSS_DOMAIN_MESSAGE_SOURCE_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ENTERED_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MESSAGE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"crossDomainMessageSender\",\"inputs\":[],\"outputs\":[{\"name\":\"_sender\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"crossDomainMessageSource\",\"inputs\":[],\"outputs\":[{\"name\":\"_source\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"messageNonce\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"relayMessage\",\"inputs\":[{\"name\":\"_destination\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_source\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"sendMessage\",\"inputs\":[{\"name\":\"_destination\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_target\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"successfulMessages\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"FailedRelayedMessage\",\"inputs\":[{\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RelayedMessage\",\"inputs\":[{\"name\":\"msgHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SentMessage\",\"inputs\":[{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":true}]", + Bin: "0x608060405234801561000f575f80fd5b50610ec28061001d5f395ff3fe6080604052600436106100b8575f3560e01c806354fd4d5011610071578063b1b1b2091161004c578063b1b1b20914610225578063b1f35f2c14610263578063ecc7042814610296575f80fd5b806354fd4d501461018a5780637056f41f146101df5780638fe5a280146101f2575f80fd5b806338ffde18116100a157806338ffde18146100f85780633f827a5a146101315780634483a8d314610157575f80fd5b80631ecd26f2146100bc57806324794462146100d1575b5f80fd5b6100cf6100ca366004610b3d565b6102ca565b005b3480156100dc575f80fd5b506100e56107cb565b6040519081526020015b60405180910390f35b348015610103575f80fd5b5061010c610825565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ef565b34801561013c575f80fd5b506101445f81565b60405161ffff90911681526020016100ef565b348015610162575f80fd5b506100e57f6705f1f7a14e02595ec471f99cf251f123c2b0258ceb26554fcae9056c389a5181565b348015610195575f80fd5b506101d26040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516100ef9190610ca6565b6100cf6101ed366004610cbf565b61087f565b3480156101fd575f80fd5b506100e57f711dfa3259c842fffc17d6e1f1e0fc5927756133a2345ca56b4cb8178589fee781565b348015610230575f80fd5b5061025361023f366004610d41565b5f6020819052908152604090205460ff1681565b60405190151581526020016100ef565b34801561026e575f80fd5b506100e57fb83444d07072b122e2e72a669ce32857d892345c19856f4e7142d06a167ab3f381565b3480156102a1575f80fd5b506001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff166100e5565b3373420000000000000000000000000000000000002214610372576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f4c32546f4c3243726f7373446f6d61696e4d657373656e6765723a2073656e6460448201527f6572206e6f742043726f73734c32496e626f780000000000000000000000000060648201526084015b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff1673420000000000000000000000000000000000002273ffffffffffffffffffffffffffffffffffffffff1663938b5f326040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103e6573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061040a9190610d58565b73ffffffffffffffffffffffffffffffffffffffff16146104d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c32546f4c3243726f7373446f6d61696e4d657373656e6765723a2043726f7360448201527f734c32496e626f78206f726967696e206e6f74207468697320636f6e7472616360648201527f7400000000000000000000000000000000000000000000000000000000000000608482015260a401610369565b468614610562576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c32546f4c3243726f7373446f6d61696e4d657373656e6765723a206465737460448201527f696e6174696f6e206e6f74207468697320636861696e000000000000000000006064820152608401610369565b7fffffffffffffffffffffffffbdffffffffffffffffffffffffffffffffffffde73ffffffffffffffffffffffffffffffffffffffff831601610627576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c32546f4c3243726f7373446f6d61696e4d657373656e6765723a2043726f7360448201527f734c32496e626f782063616e6e6f742063616c6c20697473656c6600000000006064820152608401610369565b5f86868686868660405160200161064396959493929190610d73565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301205f8181529283905291205490915060ff1615610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f4c32546f4c3243726f7373446f6d61696e4d657373656e6765723a206d65737360448201527f61676520616c72656164792072656c61796564000000000000000000000000006064820152608401610369565b6107218685610a6a565b5f61072c8484610ad8565b90508015610796575f8281526020819052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26107c1565b60405182907f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f905f90a25b5050505050505050565b5f7f6705f1f7a14e02595ec471f99cf251f123c2b0258ceb26554fcae9056c389a515c6107ff5763bca35af65f526004601cfd5b507f711dfa3259c842fffc17d6e1f1e0fc5927756133a2345ca56b4cb8178589fee75c90565b5f7f6705f1f7a14e02595ec471f99cf251f123c2b0258ceb26554fcae9056c389a515c6108595763bca35af65f526004601cfd5b507fb83444d07072b122e2e72a669ce32857d892345c19856f4e7142d06a167ab3f35c90565b46840361090e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c32546f4c3243726f7373446f6d61696e4d657373656e6765723a2063616e6e60448201527f6f742073656e64206d65737361676520746f2073656c660000000000000000006064820152608401610369565b5f844661093a6001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b338787876040516024016109549796959493929190610dc9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1ecd26f200000000000000000000000000000000000000000000000000000000179052519091506109d9908290610ca6565b60405180910390a0600180547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16905f610a1083610e54565b91906101000a8154817dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550505050505050565b60017f6705f1f7a14e02595ec471f99cf251f123c2b0258ceb26554fcae9056c389a515d817f711dfa3259c842fffc17d6e1f1e0fc5927756133a2345ca56b4cb8178589fee75d807fb83444d07072b122e2e72a669ce32857d892345c19856f4e7142d06a167ab3f35d5050565b5f805f83516020850134875af19392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b0d575f80fd5b50565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f805f805f8060c08789031215610b52575f80fd5b8635955060208701359450604087013593506060870135610b7281610aec565b92506080870135610b8281610aec565b915060a087013567ffffffffffffffff80821115610b9e575f80fd5b818901915089601f830112610bb1575f80fd5b813581811115610bc357610bc3610b10565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610c0957610c09610b10565b816040528281528c6020848701011115610c21575f80fd5b826020860160208301375f6020848301015280955050505050509295509295509295565b5f81518084525f5b81811015610c6957602081850181015186830182015201610c4d565b505f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081525f610cb86020830184610c45565b9392505050565b5f805f8060608587031215610cd2575f80fd5b843593506020850135610ce481610aec565b9250604085013567ffffffffffffffff80821115610d00575f80fd5b818701915087601f830112610d13575f80fd5b813581811115610d21575f80fd5b886020828501011115610d32575f80fd5b95989497505060200194505050565b5f60208284031215610d51575f80fd5b5035919050565b5f60208284031215610d68575f80fd5b8151610cb881610aec565b8681528560208201528460408201525f73ffffffffffffffffffffffffffffffffffffffff808616606084015280851660808401525060c060a0830152610dbd60c0830184610c45565b98975050505050505050565b8781528660208201528560408201525f73ffffffffffffffffffffffffffffffffffffffff808716606084015280861660808401525060c060a08301528260c0830152828460e08401375f60e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b5f7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808316818103610eab577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b600101939250505056fea164736f6c6343000818000a", +} + +// L2ToL2CrossDomainMessengerABI is the input ABI used to generate the binding from. +// Deprecated: Use L2ToL2CrossDomainMessengerMetaData.ABI instead. +var L2ToL2CrossDomainMessengerABI = L2ToL2CrossDomainMessengerMetaData.ABI + +// L2ToL2CrossDomainMessengerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use L2ToL2CrossDomainMessengerMetaData.Bin instead. +var L2ToL2CrossDomainMessengerBin = L2ToL2CrossDomainMessengerMetaData.Bin + +// DeployL2ToL2CrossDomainMessenger deploys a new Ethereum contract, binding an instance of L2ToL2CrossDomainMessenger to it. +func DeployL2ToL2CrossDomainMessenger(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *L2ToL2CrossDomainMessenger, error) { + parsed, err := L2ToL2CrossDomainMessengerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(L2ToL2CrossDomainMessengerBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &L2ToL2CrossDomainMessenger{L2ToL2CrossDomainMessengerCaller: L2ToL2CrossDomainMessengerCaller{contract: contract}, L2ToL2CrossDomainMessengerTransactor: L2ToL2CrossDomainMessengerTransactor{contract: contract}, L2ToL2CrossDomainMessengerFilterer: L2ToL2CrossDomainMessengerFilterer{contract: contract}}, nil +} + +// L2ToL2CrossDomainMessenger is an auto generated Go binding around an Ethereum contract. +type L2ToL2CrossDomainMessenger struct { + L2ToL2CrossDomainMessengerCaller // Read-only binding to the contract + L2ToL2CrossDomainMessengerTransactor // Write-only binding to the contract + L2ToL2CrossDomainMessengerFilterer // Log filterer for contract events +} + +// L2ToL2CrossDomainMessengerCaller is an auto generated read-only Go binding around an Ethereum contract. +type L2ToL2CrossDomainMessengerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// L2ToL2CrossDomainMessengerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type L2ToL2CrossDomainMessengerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// L2ToL2CrossDomainMessengerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type L2ToL2CrossDomainMessengerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// L2ToL2CrossDomainMessengerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type L2ToL2CrossDomainMessengerSession struct { + Contract *L2ToL2CrossDomainMessenger // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// L2ToL2CrossDomainMessengerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type L2ToL2CrossDomainMessengerCallerSession struct { + Contract *L2ToL2CrossDomainMessengerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// L2ToL2CrossDomainMessengerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type L2ToL2CrossDomainMessengerTransactorSession struct { + Contract *L2ToL2CrossDomainMessengerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// L2ToL2CrossDomainMessengerRaw is an auto generated low-level Go binding around an Ethereum contract. +type L2ToL2CrossDomainMessengerRaw struct { + Contract *L2ToL2CrossDomainMessenger // Generic contract binding to access the raw methods on +} + +// L2ToL2CrossDomainMessengerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type L2ToL2CrossDomainMessengerCallerRaw struct { + Contract *L2ToL2CrossDomainMessengerCaller // Generic read-only contract binding to access the raw methods on +} + +// L2ToL2CrossDomainMessengerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type L2ToL2CrossDomainMessengerTransactorRaw struct { + Contract *L2ToL2CrossDomainMessengerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewL2ToL2CrossDomainMessenger creates a new instance of L2ToL2CrossDomainMessenger, bound to a specific deployed contract. +func NewL2ToL2CrossDomainMessenger(address common.Address, backend bind.ContractBackend) (*L2ToL2CrossDomainMessenger, error) { + contract, err := bindL2ToL2CrossDomainMessenger(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &L2ToL2CrossDomainMessenger{L2ToL2CrossDomainMessengerCaller: L2ToL2CrossDomainMessengerCaller{contract: contract}, L2ToL2CrossDomainMessengerTransactor: L2ToL2CrossDomainMessengerTransactor{contract: contract}, L2ToL2CrossDomainMessengerFilterer: L2ToL2CrossDomainMessengerFilterer{contract: contract}}, nil +} + +// NewL2ToL2CrossDomainMessengerCaller creates a new read-only instance of L2ToL2CrossDomainMessenger, bound to a specific deployed contract. +func NewL2ToL2CrossDomainMessengerCaller(address common.Address, caller bind.ContractCaller) (*L2ToL2CrossDomainMessengerCaller, error) { + contract, err := bindL2ToL2CrossDomainMessenger(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &L2ToL2CrossDomainMessengerCaller{contract: contract}, nil +} + +// NewL2ToL2CrossDomainMessengerTransactor creates a new write-only instance of L2ToL2CrossDomainMessenger, bound to a specific deployed contract. +func NewL2ToL2CrossDomainMessengerTransactor(address common.Address, transactor bind.ContractTransactor) (*L2ToL2CrossDomainMessengerTransactor, error) { + contract, err := bindL2ToL2CrossDomainMessenger(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &L2ToL2CrossDomainMessengerTransactor{contract: contract}, nil +} + +// NewL2ToL2CrossDomainMessengerFilterer creates a new log filterer instance of L2ToL2CrossDomainMessenger, bound to a specific deployed contract. +func NewL2ToL2CrossDomainMessengerFilterer(address common.Address, filterer bind.ContractFilterer) (*L2ToL2CrossDomainMessengerFilterer, error) { + contract, err := bindL2ToL2CrossDomainMessenger(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &L2ToL2CrossDomainMessengerFilterer{contract: contract}, nil +} + +// bindL2ToL2CrossDomainMessenger binds a generic wrapper to an already deployed contract. +func bindL2ToL2CrossDomainMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(L2ToL2CrossDomainMessengerABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _L2ToL2CrossDomainMessenger.Contract.L2ToL2CrossDomainMessengerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _L2ToL2CrossDomainMessenger.Contract.L2ToL2CrossDomainMessengerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _L2ToL2CrossDomainMessenger.Contract.L2ToL2CrossDomainMessengerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _L2ToL2CrossDomainMessenger.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _L2ToL2CrossDomainMessenger.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _L2ToL2CrossDomainMessenger.Contract.contract.Transact(opts, method, params...) +} + +// CROSSDOMAINMESSAGESENDERSLOT is a free data retrieval call binding the contract method 0xb1f35f2c. +// +// Solidity: function CROSS_DOMAIN_MESSAGE_SENDER_SLOT() view returns(bytes32) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCaller) CROSSDOMAINMESSAGESENDERSLOT(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _L2ToL2CrossDomainMessenger.contract.Call(opts, &out, "CROSS_DOMAIN_MESSAGE_SENDER_SLOT") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// CROSSDOMAINMESSAGESENDERSLOT is a free data retrieval call binding the contract method 0xb1f35f2c. +// +// Solidity: function CROSS_DOMAIN_MESSAGE_SENDER_SLOT() view returns(bytes32) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerSession) CROSSDOMAINMESSAGESENDERSLOT() ([32]byte, error) { + return _L2ToL2CrossDomainMessenger.Contract.CROSSDOMAINMESSAGESENDERSLOT(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// CROSSDOMAINMESSAGESENDERSLOT is a free data retrieval call binding the contract method 0xb1f35f2c. +// +// Solidity: function CROSS_DOMAIN_MESSAGE_SENDER_SLOT() view returns(bytes32) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCallerSession) CROSSDOMAINMESSAGESENDERSLOT() ([32]byte, error) { + return _L2ToL2CrossDomainMessenger.Contract.CROSSDOMAINMESSAGESENDERSLOT(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// CROSSDOMAINMESSAGESOURCESLOT is a free data retrieval call binding the contract method 0x8fe5a280. +// +// Solidity: function CROSS_DOMAIN_MESSAGE_SOURCE_SLOT() view returns(bytes32) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCaller) CROSSDOMAINMESSAGESOURCESLOT(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _L2ToL2CrossDomainMessenger.contract.Call(opts, &out, "CROSS_DOMAIN_MESSAGE_SOURCE_SLOT") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// CROSSDOMAINMESSAGESOURCESLOT is a free data retrieval call binding the contract method 0x8fe5a280. +// +// Solidity: function CROSS_DOMAIN_MESSAGE_SOURCE_SLOT() view returns(bytes32) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerSession) CROSSDOMAINMESSAGESOURCESLOT() ([32]byte, error) { + return _L2ToL2CrossDomainMessenger.Contract.CROSSDOMAINMESSAGESOURCESLOT(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// CROSSDOMAINMESSAGESOURCESLOT is a free data retrieval call binding the contract method 0x8fe5a280. +// +// Solidity: function CROSS_DOMAIN_MESSAGE_SOURCE_SLOT() view returns(bytes32) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCallerSession) CROSSDOMAINMESSAGESOURCESLOT() ([32]byte, error) { + return _L2ToL2CrossDomainMessenger.Contract.CROSSDOMAINMESSAGESOURCESLOT(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// ENTEREDSLOT is a free data retrieval call binding the contract method 0x4483a8d3. +// +// Solidity: function ENTERED_SLOT() view returns(bytes32) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCaller) ENTEREDSLOT(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _L2ToL2CrossDomainMessenger.contract.Call(opts, &out, "ENTERED_SLOT") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ENTEREDSLOT is a free data retrieval call binding the contract method 0x4483a8d3. +// +// Solidity: function ENTERED_SLOT() view returns(bytes32) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerSession) ENTEREDSLOT() ([32]byte, error) { + return _L2ToL2CrossDomainMessenger.Contract.ENTEREDSLOT(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// ENTEREDSLOT is a free data retrieval call binding the contract method 0x4483a8d3. +// +// Solidity: function ENTERED_SLOT() view returns(bytes32) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCallerSession) ENTEREDSLOT() ([32]byte, error) { + return _L2ToL2CrossDomainMessenger.Contract.ENTEREDSLOT(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// MESSAGEVERSION is a free data retrieval call binding the contract method 0x3f827a5a. +// +// Solidity: function MESSAGE_VERSION() view returns(uint16) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCaller) MESSAGEVERSION(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _L2ToL2CrossDomainMessenger.contract.Call(opts, &out, "MESSAGE_VERSION") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +// MESSAGEVERSION is a free data retrieval call binding the contract method 0x3f827a5a. +// +// Solidity: function MESSAGE_VERSION() view returns(uint16) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerSession) MESSAGEVERSION() (uint16, error) { + return _L2ToL2CrossDomainMessenger.Contract.MESSAGEVERSION(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// MESSAGEVERSION is a free data retrieval call binding the contract method 0x3f827a5a. +// +// Solidity: function MESSAGE_VERSION() view returns(uint16) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCallerSession) MESSAGEVERSION() (uint16, error) { + return _L2ToL2CrossDomainMessenger.Contract.MESSAGEVERSION(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// CrossDomainMessageSender is a free data retrieval call binding the contract method 0x38ffde18. +// +// Solidity: function crossDomainMessageSender() view returns(address _sender) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCaller) CrossDomainMessageSender(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _L2ToL2CrossDomainMessenger.contract.Call(opts, &out, "crossDomainMessageSender") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// CrossDomainMessageSender is a free data retrieval call binding the contract method 0x38ffde18. +// +// Solidity: function crossDomainMessageSender() view returns(address _sender) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerSession) CrossDomainMessageSender() (common.Address, error) { + return _L2ToL2CrossDomainMessenger.Contract.CrossDomainMessageSender(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// CrossDomainMessageSender is a free data retrieval call binding the contract method 0x38ffde18. +// +// Solidity: function crossDomainMessageSender() view returns(address _sender) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCallerSession) CrossDomainMessageSender() (common.Address, error) { + return _L2ToL2CrossDomainMessenger.Contract.CrossDomainMessageSender(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// CrossDomainMessageSource is a free data retrieval call binding the contract method 0x24794462. +// +// Solidity: function crossDomainMessageSource() view returns(uint256 _source) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCaller) CrossDomainMessageSource(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _L2ToL2CrossDomainMessenger.contract.Call(opts, &out, "crossDomainMessageSource") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// CrossDomainMessageSource is a free data retrieval call binding the contract method 0x24794462. +// +// Solidity: function crossDomainMessageSource() view returns(uint256 _source) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerSession) CrossDomainMessageSource() (*big.Int, error) { + return _L2ToL2CrossDomainMessenger.Contract.CrossDomainMessageSource(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// CrossDomainMessageSource is a free data retrieval call binding the contract method 0x24794462. +// +// Solidity: function crossDomainMessageSource() view returns(uint256 _source) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCallerSession) CrossDomainMessageSource() (*big.Int, error) { + return _L2ToL2CrossDomainMessenger.Contract.CrossDomainMessageSource(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// MessageNonce is a free data retrieval call binding the contract method 0xecc70428. +// +// Solidity: function messageNonce() view returns(uint256) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCaller) MessageNonce(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _L2ToL2CrossDomainMessenger.contract.Call(opts, &out, "messageNonce") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MessageNonce is a free data retrieval call binding the contract method 0xecc70428. +// +// Solidity: function messageNonce() view returns(uint256) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerSession) MessageNonce() (*big.Int, error) { + return _L2ToL2CrossDomainMessenger.Contract.MessageNonce(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// MessageNonce is a free data retrieval call binding the contract method 0xecc70428. +// +// Solidity: function messageNonce() view returns(uint256) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCallerSession) MessageNonce() (*big.Int, error) { + return _L2ToL2CrossDomainMessenger.Contract.MessageNonce(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// SuccessfulMessages is a free data retrieval call binding the contract method 0xb1b1b209. +// +// Solidity: function successfulMessages(bytes32 ) view returns(bool) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCaller) SuccessfulMessages(opts *bind.CallOpts, arg0 [32]byte) (bool, error) { + var out []interface{} + err := _L2ToL2CrossDomainMessenger.contract.Call(opts, &out, "successfulMessages", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// SuccessfulMessages is a free data retrieval call binding the contract method 0xb1b1b209. +// +// Solidity: function successfulMessages(bytes32 ) view returns(bool) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerSession) SuccessfulMessages(arg0 [32]byte) (bool, error) { + return _L2ToL2CrossDomainMessenger.Contract.SuccessfulMessages(&_L2ToL2CrossDomainMessenger.CallOpts, arg0) +} + +// SuccessfulMessages is a free data retrieval call binding the contract method 0xb1b1b209. +// +// Solidity: function successfulMessages(bytes32 ) view returns(bool) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCallerSession) SuccessfulMessages(arg0 [32]byte) (bool, error) { + return _L2ToL2CrossDomainMessenger.Contract.SuccessfulMessages(&_L2ToL2CrossDomainMessenger.CallOpts, arg0) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCaller) Version(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _L2ToL2CrossDomainMessenger.contract.Call(opts, &out, "version") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerSession) Version() (string, error) { + return _L2ToL2CrossDomainMessenger.Contract.Version(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerCallerSession) Version() (string, error) { + return _L2ToL2CrossDomainMessenger.Contract.Version(&_L2ToL2CrossDomainMessenger.CallOpts) +} + +// RelayMessage is a paid mutator transaction binding the contract method 0x1ecd26f2. +// +// Solidity: function relayMessage(uint256 _destination, uint256 _source, uint256 _nonce, address _sender, address _target, bytes _message) payable returns() +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerTransactor) RelayMessage(opts *bind.TransactOpts, _destination *big.Int, _source *big.Int, _nonce *big.Int, _sender common.Address, _target common.Address, _message []byte) (*types.Transaction, error) { + return _L2ToL2CrossDomainMessenger.contract.Transact(opts, "relayMessage", _destination, _source, _nonce, _sender, _target, _message) +} + +// RelayMessage is a paid mutator transaction binding the contract method 0x1ecd26f2. +// +// Solidity: function relayMessage(uint256 _destination, uint256 _source, uint256 _nonce, address _sender, address _target, bytes _message) payable returns() +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerSession) RelayMessage(_destination *big.Int, _source *big.Int, _nonce *big.Int, _sender common.Address, _target common.Address, _message []byte) (*types.Transaction, error) { + return _L2ToL2CrossDomainMessenger.Contract.RelayMessage(&_L2ToL2CrossDomainMessenger.TransactOpts, _destination, _source, _nonce, _sender, _target, _message) +} + +// RelayMessage is a paid mutator transaction binding the contract method 0x1ecd26f2. +// +// Solidity: function relayMessage(uint256 _destination, uint256 _source, uint256 _nonce, address _sender, address _target, bytes _message) payable returns() +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerTransactorSession) RelayMessage(_destination *big.Int, _source *big.Int, _nonce *big.Int, _sender common.Address, _target common.Address, _message []byte) (*types.Transaction, error) { + return _L2ToL2CrossDomainMessenger.Contract.RelayMessage(&_L2ToL2CrossDomainMessenger.TransactOpts, _destination, _source, _nonce, _sender, _target, _message) +} + +// SendMessage is a paid mutator transaction binding the contract method 0x7056f41f. +// +// Solidity: function sendMessage(uint256 _destination, address _target, bytes _message) payable returns() +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerTransactor) SendMessage(opts *bind.TransactOpts, _destination *big.Int, _target common.Address, _message []byte) (*types.Transaction, error) { + return _L2ToL2CrossDomainMessenger.contract.Transact(opts, "sendMessage", _destination, _target, _message) +} + +// SendMessage is a paid mutator transaction binding the contract method 0x7056f41f. +// +// Solidity: function sendMessage(uint256 _destination, address _target, bytes _message) payable returns() +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerSession) SendMessage(_destination *big.Int, _target common.Address, _message []byte) (*types.Transaction, error) { + return _L2ToL2CrossDomainMessenger.Contract.SendMessage(&_L2ToL2CrossDomainMessenger.TransactOpts, _destination, _target, _message) +} + +// SendMessage is a paid mutator transaction binding the contract method 0x7056f41f. +// +// Solidity: function sendMessage(uint256 _destination, address _target, bytes _message) payable returns() +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerTransactorSession) SendMessage(_destination *big.Int, _target common.Address, _message []byte) (*types.Transaction, error) { + return _L2ToL2CrossDomainMessenger.Contract.SendMessage(&_L2ToL2CrossDomainMessenger.TransactOpts, _destination, _target, _message) +} + +// L2ToL2CrossDomainMessengerFailedRelayedMessageIterator is returned from FilterFailedRelayedMessage and is used to iterate over the raw logs and unpacked data for FailedRelayedMessage events raised by the L2ToL2CrossDomainMessenger contract. +type L2ToL2CrossDomainMessengerFailedRelayedMessageIterator struct { + Event *L2ToL2CrossDomainMessengerFailedRelayedMessage // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *L2ToL2CrossDomainMessengerFailedRelayedMessageIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(L2ToL2CrossDomainMessengerFailedRelayedMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(L2ToL2CrossDomainMessengerFailedRelayedMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *L2ToL2CrossDomainMessengerFailedRelayedMessageIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *L2ToL2CrossDomainMessengerFailedRelayedMessageIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// L2ToL2CrossDomainMessengerFailedRelayedMessage represents a FailedRelayedMessage event raised by the L2ToL2CrossDomainMessenger contract. +type L2ToL2CrossDomainMessengerFailedRelayedMessage struct { + MsgHash [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterFailedRelayedMessage is a free log retrieval operation binding the contract event 0x99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f. +// +// Solidity: event FailedRelayedMessage(bytes32 indexed msgHash) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerFilterer) FilterFailedRelayedMessage(opts *bind.FilterOpts, msgHash [][32]byte) (*L2ToL2CrossDomainMessengerFailedRelayedMessageIterator, error) { + + var msgHashRule []interface{} + for _, msgHashItem := range msgHash { + msgHashRule = append(msgHashRule, msgHashItem) + } + + logs, sub, err := _L2ToL2CrossDomainMessenger.contract.FilterLogs(opts, "FailedRelayedMessage", msgHashRule) + if err != nil { + return nil, err + } + return &L2ToL2CrossDomainMessengerFailedRelayedMessageIterator{contract: _L2ToL2CrossDomainMessenger.contract, event: "FailedRelayedMessage", logs: logs, sub: sub}, nil +} + +// WatchFailedRelayedMessage is a free log subscription operation binding the contract event 0x99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f. +// +// Solidity: event FailedRelayedMessage(bytes32 indexed msgHash) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerFilterer) WatchFailedRelayedMessage(opts *bind.WatchOpts, sink chan<- *L2ToL2CrossDomainMessengerFailedRelayedMessage, msgHash [][32]byte) (event.Subscription, error) { + + var msgHashRule []interface{} + for _, msgHashItem := range msgHash { + msgHashRule = append(msgHashRule, msgHashItem) + } + + logs, sub, err := _L2ToL2CrossDomainMessenger.contract.WatchLogs(opts, "FailedRelayedMessage", msgHashRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(L2ToL2CrossDomainMessengerFailedRelayedMessage) + if err := _L2ToL2CrossDomainMessenger.contract.UnpackLog(event, "FailedRelayedMessage", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseFailedRelayedMessage is a log parse operation binding the contract event 0x99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f. +// +// Solidity: event FailedRelayedMessage(bytes32 indexed msgHash) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerFilterer) ParseFailedRelayedMessage(log types.Log) (*L2ToL2CrossDomainMessengerFailedRelayedMessage, error) { + event := new(L2ToL2CrossDomainMessengerFailedRelayedMessage) + if err := _L2ToL2CrossDomainMessenger.contract.UnpackLog(event, "FailedRelayedMessage", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// L2ToL2CrossDomainMessengerRelayedMessageIterator is returned from FilterRelayedMessage and is used to iterate over the raw logs and unpacked data for RelayedMessage events raised by the L2ToL2CrossDomainMessenger contract. +type L2ToL2CrossDomainMessengerRelayedMessageIterator struct { + Event *L2ToL2CrossDomainMessengerRelayedMessage // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *L2ToL2CrossDomainMessengerRelayedMessageIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(L2ToL2CrossDomainMessengerRelayedMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(L2ToL2CrossDomainMessengerRelayedMessage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *L2ToL2CrossDomainMessengerRelayedMessageIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *L2ToL2CrossDomainMessengerRelayedMessageIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// L2ToL2CrossDomainMessengerRelayedMessage represents a RelayedMessage event raised by the L2ToL2CrossDomainMessenger contract. +type L2ToL2CrossDomainMessengerRelayedMessage struct { + MsgHash [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRelayedMessage is a free log retrieval operation binding the contract event 0x4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c. +// +// Solidity: event RelayedMessage(bytes32 indexed msgHash) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerFilterer) FilterRelayedMessage(opts *bind.FilterOpts, msgHash [][32]byte) (*L2ToL2CrossDomainMessengerRelayedMessageIterator, error) { + + var msgHashRule []interface{} + for _, msgHashItem := range msgHash { + msgHashRule = append(msgHashRule, msgHashItem) + } + + logs, sub, err := _L2ToL2CrossDomainMessenger.contract.FilterLogs(opts, "RelayedMessage", msgHashRule) + if err != nil { + return nil, err + } + return &L2ToL2CrossDomainMessengerRelayedMessageIterator{contract: _L2ToL2CrossDomainMessenger.contract, event: "RelayedMessage", logs: logs, sub: sub}, nil +} + +// WatchRelayedMessage is a free log subscription operation binding the contract event 0x4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c. +// +// Solidity: event RelayedMessage(bytes32 indexed msgHash) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerFilterer) WatchRelayedMessage(opts *bind.WatchOpts, sink chan<- *L2ToL2CrossDomainMessengerRelayedMessage, msgHash [][32]byte) (event.Subscription, error) { + + var msgHashRule []interface{} + for _, msgHashItem := range msgHash { + msgHashRule = append(msgHashRule, msgHashItem) + } + + logs, sub, err := _L2ToL2CrossDomainMessenger.contract.WatchLogs(opts, "RelayedMessage", msgHashRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(L2ToL2CrossDomainMessengerRelayedMessage) + if err := _L2ToL2CrossDomainMessenger.contract.UnpackLog(event, "RelayedMessage", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRelayedMessage is a log parse operation binding the contract event 0x4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c. +// +// Solidity: event RelayedMessage(bytes32 indexed msgHash) +func (_L2ToL2CrossDomainMessenger *L2ToL2CrossDomainMessengerFilterer) ParseRelayedMessage(log types.Log) (*L2ToL2CrossDomainMessengerRelayedMessage, error) { + event := new(L2ToL2CrossDomainMessengerRelayedMessage) + if err := _L2ToL2CrossDomainMessenger.contract.UnpackLog(event, "RelayedMessage", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/op-bindings/bindings/l2tol2crossdomainmessenger_more.go b/op-bindings/bindings/l2tol2crossdomainmessenger_more.go new file mode 100644 index 0000000000000..9e94df2446ca1 --- /dev/null +++ b/op-bindings/bindings/l2tol2crossdomainmessenger_more.go @@ -0,0 +1,27 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "encoding/json" + + "github.com/ethereum-optimism/optimism/op-bindings/solc" +) + +const L2ToL2CrossDomainMessengerStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L2/L2ToL2CrossDomainMessenger.sol:L2ToL2CrossDomainMessenger\",\"label\":\"successfulMessages\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_bytes32,t_bool)\"},{\"astId\":1001,\"contract\":\"src/L2/L2ToL2CrossDomainMessenger.sol:L2ToL2CrossDomainMessenger\",\"label\":\"msgNonce\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_uint240\"}],\"types\":{\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_bytes32\":{\"encoding\":\"inplace\",\"label\":\"bytes32\",\"numberOfBytes\":\"32\"},\"t_mapping(t_bytes32,t_bool)\":{\"encoding\":\"mapping\",\"label\":\"mapping(bytes32 =\u003e bool)\",\"numberOfBytes\":\"32\",\"key\":\"t_bytes32\",\"value\":\"t_bool\"},\"t_uint240\":{\"encoding\":\"inplace\",\"label\":\"uint240\",\"numberOfBytes\":\"30\"}}}" + +var L2ToL2CrossDomainMessengerStorageLayout = new(solc.StorageLayout) + +var L2ToL2CrossDomainMessengerDeployedBin = "0x6080604052600436106100b8575f3560e01c806354fd4d5011610071578063b1b1b2091161004c578063b1b1b20914610225578063b1f35f2c14610263578063ecc7042814610296575f80fd5b806354fd4d501461018a5780637056f41f146101df5780638fe5a280146101f2575f80fd5b806338ffde18116100a157806338ffde18146100f85780633f827a5a146101315780634483a8d314610157575f80fd5b80631ecd26f2146100bc57806324794462146100d1575b5f80fd5b6100cf6100ca366004610b3d565b6102ca565b005b3480156100dc575f80fd5b506100e56107cb565b6040519081526020015b60405180910390f35b348015610103575f80fd5b5061010c610825565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ef565b34801561013c575f80fd5b506101445f81565b60405161ffff90911681526020016100ef565b348015610162575f80fd5b506100e57f6705f1f7a14e02595ec471f99cf251f123c2b0258ceb26554fcae9056c389a5181565b348015610195575f80fd5b506101d26040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516100ef9190610ca6565b6100cf6101ed366004610cbf565b61087f565b3480156101fd575f80fd5b506100e57f711dfa3259c842fffc17d6e1f1e0fc5927756133a2345ca56b4cb8178589fee781565b348015610230575f80fd5b5061025361023f366004610d41565b5f6020819052908152604090205460ff1681565b60405190151581526020016100ef565b34801561026e575f80fd5b506100e57fb83444d07072b122e2e72a669ce32857d892345c19856f4e7142d06a167ab3f381565b3480156102a1575f80fd5b506001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff166100e5565b3373420000000000000000000000000000000000002214610372576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f4c32546f4c3243726f7373446f6d61696e4d657373656e6765723a2073656e6460448201527f6572206e6f742043726f73734c32496e626f780000000000000000000000000060648201526084015b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff1673420000000000000000000000000000000000002273ffffffffffffffffffffffffffffffffffffffff1663938b5f326040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103e6573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061040a9190610d58565b73ffffffffffffffffffffffffffffffffffffffff16146104d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604160248201527f4c32546f4c3243726f7373446f6d61696e4d657373656e6765723a2043726f7360448201527f734c32496e626f78206f726967696e206e6f74207468697320636f6e7472616360648201527f7400000000000000000000000000000000000000000000000000000000000000608482015260a401610369565b468614610562576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c32546f4c3243726f7373446f6d61696e4d657373656e6765723a206465737460448201527f696e6174696f6e206e6f74207468697320636861696e000000000000000000006064820152608401610369565b7fffffffffffffffffffffffffbdffffffffffffffffffffffffffffffffffffde73ffffffffffffffffffffffffffffffffffffffff831601610627576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f4c32546f4c3243726f7373446f6d61696e4d657373656e6765723a2043726f7360448201527f734c32496e626f782063616e6e6f742063616c6c20697473656c6600000000006064820152608401610369565b5f86868686868660405160200161064396959493929190610d73565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301205f8181529283905291205490915060ff1615610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f4c32546f4c3243726f7373446f6d61696e4d657373656e6765723a206d65737360448201527f61676520616c72656164792072656c61796564000000000000000000000000006064820152608401610369565b6107218685610a6a565b5f61072c8484610ad8565b90508015610796575f8281526020819052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a26107c1565b60405182907f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f905f90a25b5050505050505050565b5f7f6705f1f7a14e02595ec471f99cf251f123c2b0258ceb26554fcae9056c389a515c6107ff5763bca35af65f526004601cfd5b507f711dfa3259c842fffc17d6e1f1e0fc5927756133a2345ca56b4cb8178589fee75c90565b5f7f6705f1f7a14e02595ec471f99cf251f123c2b0258ceb26554fcae9056c389a515c6108595763bca35af65f526004601cfd5b507fb83444d07072b122e2e72a669ce32857d892345c19856f4e7142d06a167ab3f35c90565b46840361090e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c32546f4c3243726f7373446f6d61696e4d657373656e6765723a2063616e6e60448201527f6f742073656e64206d65737361676520746f2073656c660000000000000000006064820152608401610369565b5f844661093a6001547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b338787876040516024016109549796959493929190610dc9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1ecd26f200000000000000000000000000000000000000000000000000000000179052519091506109d9908290610ca6565b60405180910390a0600180547dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16905f610a1083610e54565b91906101000a8154817dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550505050505050565b60017f6705f1f7a14e02595ec471f99cf251f123c2b0258ceb26554fcae9056c389a515d817f711dfa3259c842fffc17d6e1f1e0fc5927756133a2345ca56b4cb8178589fee75d807fb83444d07072b122e2e72a669ce32857d892345c19856f4e7142d06a167ab3f35d5050565b5f805f83516020850134875af19392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610b0d575f80fd5b50565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f805f805f8060c08789031215610b52575f80fd5b8635955060208701359450604087013593506060870135610b7281610aec565b92506080870135610b8281610aec565b915060a087013567ffffffffffffffff80821115610b9e575f80fd5b818901915089601f830112610bb1575f80fd5b813581811115610bc357610bc3610b10565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610c0957610c09610b10565b816040528281528c6020848701011115610c21575f80fd5b826020860160208301375f6020848301015280955050505050509295509295509295565b5f81518084525f5b81811015610c6957602081850181015186830182015201610c4d565b505f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081525f610cb86020830184610c45565b9392505050565b5f805f8060608587031215610cd2575f80fd5b843593506020850135610ce481610aec565b9250604085013567ffffffffffffffff80821115610d00575f80fd5b818701915087601f830112610d13575f80fd5b813581811115610d21575f80fd5b886020828501011115610d32575f80fd5b95989497505060200194505050565b5f60208284031215610d51575f80fd5b5035919050565b5f60208284031215610d68575f80fd5b8151610cb881610aec565b8681528560208201528460408201525f73ffffffffffffffffffffffffffffffffffffffff808616606084015280851660808401525060c060a0830152610dbd60c0830184610c45565b98975050505050505050565b8781528660208201528560408201525f73ffffffffffffffffffffffffffffffffffffffff808716606084015280861660808401525060c060a08301528260c0830152828460e08401375f60e0848401015260e07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905098975050505050505050565b5f7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808316818103610eab577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b600101939250505056fea164736f6c6343000818000a" + + +func init() { + if err := json.Unmarshal([]byte(L2ToL2CrossDomainMessengerStorageLayoutJSON), L2ToL2CrossDomainMessengerStorageLayout); err != nil { + panic(err) + } + + layouts["L2ToL2CrossDomainMessenger"] = L2ToL2CrossDomainMessengerStorageLayout + deployedBytecodes["L2ToL2CrossDomainMessenger"] = L2ToL2CrossDomainMessengerDeployedBin + immutableReferences["L2ToL2CrossDomainMessenger"] = false +} diff --git a/op-bindings/predeploys/addresses.go b/op-bindings/predeploys/addresses.go index 9f2c363a603c6..503649a7fafbf 100644 --- a/op-bindings/predeploys/addresses.go +++ b/op-bindings/predeploys/addresses.go @@ -36,6 +36,7 @@ const ( Permit2 = "0x000000000022D473030F116dDEE9F6B43aC78BA3" SenderCreator = "0x7fc98430eaedbb6070b35b39d798725049088348" EntryPoint = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" + L2ToL2CrossDomainMessenger = "0x4200000000000000000000000000000000000023" CrossL2Inbox = "0x4200000000000000000000000000000000000022" ) @@ -70,6 +71,7 @@ var ( Permit2Addr = common.HexToAddress(Permit2) SenderCreatorAddr = common.HexToAddress(SenderCreator) EntryPointAddr = common.HexToAddress(EntryPoint) + L2ToL2CrossDomainMessengerAddr = common.HexToAddress(L2ToL2CrossDomainMessenger) CrossL2InboxAddr = common.HexToAddress(CrossL2Inbox) Predeploys = make(map[string]*Predeploy) @@ -147,6 +149,9 @@ func init() { Address: EntryPointAddr, ProxyDisabled: true, } + Predeploys["L2ToL2CrossDomainMessenger"] = &Predeploy{ + Address: L2ToL2CrossDomainMessengerAddr, + } for _, predeploy := range Predeploys { PredeploysByAddress[predeploy.Address] = predeploy diff --git a/packages/contracts-bedrock/foundry.toml b/packages/contracts-bedrock/foundry.toml index e33ebf83b7829..73efd4e888b81 100644 --- a/packages/contracts-bedrock/foundry.toml +++ b/packages/contracts-bedrock/foundry.toml @@ -26,21 +26,21 @@ extra_output = ['devdoc', 'userdoc', 'metadata', 'storageLayout'] bytecode_hash = 'none' build_info_path = 'artifacts/build-info' evm_version = "cancun" -ignored_error_codes = [2394] +ignored_error_codes = [2394, 5574, 3860] # Test / Script Runner Settings ffi = true fs_permissions = [ - { access='read-write', path='./.resource-metering.csv' }, - { access='read-write', path='./snapshots/' }, - { access='read-write', path='./deployments/' }, - { access='read', path='./deploy-config/' }, - { access='read', path='./periphery-deploy-config/' }, - { access='read', path='./broadcast/' }, - { access='read', path = './forge-artifacts/' }, - { access='write', path='./semver-lock.json' }, - { access='read-write', path='./.testdata/' }, - { access='read', path='./kout-deployment' } + { access = 'read-write', path = './.resource-metering.csv' }, + { access = 'read-write', path = './snapshots/' }, + { access = 'read-write', path = './deployments/' }, + { access = 'read', path = './deploy-config/' }, + { access = 'read', path = './periphery-deploy-config/' }, + { access = 'read', path = './broadcast/' }, + { access = 'read', path = './forge-artifacts/' }, + { access = 'write', path = './semver-lock.json' }, + { access = 'read-write', path = './.testdata/' }, + { access = 'read', path = './kout-deployment' }, ] libs = ["node_modules", "lib"] @@ -48,10 +48,10 @@ libs = ["node_modules", "lib"] runs = 64 [fmt] -line_length=120 -multiline_func_header='all' -bracket_spacing=true -wrap_comments=true +line_length = 120 +multiline_func_header = 'all' +bracket_spacing = true +wrap_comments = true ignore = ['src/vendor/WETH9.sol'] ################################################################ diff --git a/packages/contracts-bedrock/scripts/Artifacts.s.sol b/packages/contracts-bedrock/scripts/Artifacts.s.sol index fe6f094449925..c6b5d0c62c578 100644 --- a/packages/contracts-bedrock/scripts/Artifacts.s.sol +++ b/packages/contracts-bedrock/scripts/Artifacts.s.sol @@ -149,6 +149,8 @@ abstract contract Artifacts { return payable(Predeploys.SCHEMA_REGISTRY); } else if (digest == keccak256(bytes("EAS"))) { return payable(Predeploys.EAS); + } else if (digest == keccak256(bytes("L2ToL2CrossDomainMessenger"))) { + return payable(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER); } else if (digest == keccak256(bytes("CrossL2Inbox"))) { return payable(Predeploys.CROSS_L2_INBOX); } diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 1e8bee36528b2..e2995d1f62f79 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -87,6 +87,10 @@ "initCodeHash": "0x08bbede75cd6dfd076903b8f04d24f82fa7881576c135825098778632e37eebc", "sourceCodeHash": "0x8388b9b8075f31d580fed815b66b45394e40fb1a63cd8cda2272d2c390fc908c" }, + "src/L2/L2ToL2CrossDomainMessenger.sol": { + "initCodeHash": "0x72a427e5b6df62a988fe0d7420cb57244dbfbf2eab067cae51d2ca58feffaf85", + "sourceCodeHash": "0xc8e8ec0ed2d29452475723e89cd5ce12b891b3461e61c52d15bdc762e4f0c5bb" + }, "src/L2/SequencerFeeVault.sol": { "initCodeHash": "0xd62e193d89b1661d34031227a45ce1eade9c2a89b0bd7f362f511d03cceef294", "sourceCodeHash": "0xa304b4b556162323d69662b4dd9a1d073d55ec661494465489bb67f1e465e7b3" diff --git a/packages/contracts-bedrock/snapshots/abi/L2ToL2CrossDomainMessenger.json b/packages/contracts-bedrock/snapshots/abi/L2ToL2CrossDomainMessenger.json new file mode 100644 index 0000000000000..47d7a972174b7 --- /dev/null +++ b/packages/contracts-bedrock/snapshots/abi/L2ToL2CrossDomainMessenger.json @@ -0,0 +1,212 @@ +[ + { + "inputs": [], + "name": "CROSS_DOMAIN_MESSAGE_SENDER_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "CROSS_DOMAIN_MESSAGE_SOURCE_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MESSAGE_VERSION", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "crossDomainMessageSender", + "outputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "crossDomainMessageSource", + "outputs": [ + { + "internalType": "uint256", + "name": "_source", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "messageNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_destination", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_source", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + } + ], + "name": "relayMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_destination", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_message", + "type": "bytes" + } + ], + "name": "sendMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "successfulMessages", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "msgHash", + "type": "bytes32" + } + ], + "name": "FailedRelayedMessage", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "msgHash", + "type": "bytes32" + } + ], + "name": "RelayedMessage", + "type": "event" + }, + { + "anonymous": true, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "SentMessage", + "type": "event" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/storageLayout/L2ToL2CrossDomainMessenger.json b/packages/contracts-bedrock/snapshots/storageLayout/L2ToL2CrossDomainMessenger.json new file mode 100644 index 0000000000000..a69c85af7b2ac --- /dev/null +++ b/packages/contracts-bedrock/snapshots/storageLayout/L2ToL2CrossDomainMessenger.json @@ -0,0 +1,16 @@ +[ + { + "bytes": "32", + "label": "successfulMessages", + "offset": 0, + "slot": "0", + "type": "mapping(bytes32 => bool)" + }, + { + "bytes": "30", + "label": "msgNonce", + "offset": 0, + "slot": "1", + "type": "uint240" + } +] \ No newline at end of file diff --git a/packages/contracts-bedrock/src/L2/IL2ToL2CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L2/IL2ToL2CrossDomainMessenger.sol new file mode 100644 index 0000000000000..19a627ff9a30d --- /dev/null +++ b/packages/contracts-bedrock/src/L2/IL2ToL2CrossDomainMessenger.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title IL2ToL2CrossDomainMessenger +/// @notice Interface for the L2ToL2CrossDomainMessenger contract. +interface IL2ToL2CrossDomainMessenger { + /// @notice Retrieves the sender of the current cross domain message. + /// @return _sender Address of the sender of the current cross domain message. + function crossDomainMessageSender() external view returns (address _sender); + + /// @notice Retrieves the source of the current cross domain message. + /// @return _source Chain ID of the source of the current cross domain message. + function crossDomainMessageSource() external view returns (uint256 _source); + + /// @notice Sends a message to some target address on a destination chain. Note that if the call + /// always reverts, then the message will be unrelayable, and any ETH sent will be + /// permanently locked. The same will occur if the target on the other chain is + /// considered unsafe (see the _isUnsafeTarget() function). + /// @param _destination Chain ID of the destination chain. + /// @param _target Target contract or wallet address. + /// @param _message Message to trigger the target address with. + function sendMessage(uint256 _destination, address _target, bytes calldata _message) external payable; + + /// @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only + /// be executed via cross-chain call from the other messenger OR if the message was + /// already received once and is currently being replayed. + /// @param _destination Chain ID of the destination chain. + /// @param _nonce Nonce of the message being relayed. + /// @param _sender Address of the user who sent the message. + /// @param _source Chain ID of the source chain. + /// @param _target Address that the message is targeted at. + /// @param _message Message to send to the target. + function relayMessage( + uint256 _destination, + uint256 _source, + uint256 _nonce, + address _sender, + address _target, + bytes calldata _message + ) + external + payable; +} diff --git a/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol new file mode 100644 index 0000000000000..e6a7a656a30dd --- /dev/null +++ b/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol @@ -0,0 +1,185 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import { CrossL2Inbox } from "src/L2/CrossL2Inbox.sol"; +import { Encoding } from "src/libraries/Encoding.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { ISemver } from "src/universal/ISemver.sol"; +import { IL2ToL2CrossDomainMessenger } from "src/L2/IL2ToL2CrossDomainMessenger.sol"; + +/// @notice Thrown when a non-written tstore slot is attempted to be read from. +error NotEntered(); + +/// @custom:proxied +/// @custom:predeploy 0x4200000000000000000000000000000000000023 +/// @title L2ToL2CrossDomainMessenger +/// @notice The L2ToL2CrossDomainMessenger is a higher level abstraction on top of the CrossL2Inbox that provides +/// features necessary for secure transfers ERC20 tokens between L2 chains. Messages sent through the +/// L2ToL2CrossDomainMessenger on the source chain receive both replay protection as well as domain binding. +contract L2ToL2CrossDomainMessenger is IL2ToL2CrossDomainMessenger, ISemver { + /// @notice Transient storage slot that `entered` is stored at. + /// Equal to bytes32(uint256(keccak256("crossl2inbox.entered")) - 1) + bytes32 public constant ENTERED_SLOT = 0x6705f1f7a14e02595ec471f99cf251f123c2b0258ceb26554fcae9056c389a51; + + /// @notice Storage slot for the sender of the current cross domain message. + /// Equal to bytes32(uint256(keccak256("l2tol2crossdomainmessenger.sender")) - 1) + bytes32 public constant CROSS_DOMAIN_MESSAGE_SENDER_SLOT = + 0xb83444d07072b122e2e72a669ce32857d892345c19856f4e7142d06a167ab3f3; + + /// @notice Storage slot for the source of the current cross domain message. + /// Equal to bytes32(uint256(keccak256("l2tol2crossdomainmessenger.source")) - 1) + bytes32 public constant CROSS_DOMAIN_MESSAGE_SOURCE_SLOT = + 0x711dfa3259c842fffc17d6e1f1e0fc5927756133a2345ca56b4cb8178589fee7; + + /// @notice Current message version identifier. + uint16 public constant MESSAGE_VERSION = uint16(0); + + /// @notice Mapping of message hashes to boolean receipt values. Note that a message will only + /// be present in this mapping if it has successfully been relayed on this chain, and + /// can therefore not be relayed again. + mapping(bytes32 => bool) public successfulMessages; + + /// @notice Nonce for the next message to be sent, without the message version applied. Use the + /// messageNonce getter which will insert the message version into the nonce to give you + /// the actual nonce to be used for the message. + uint240 internal msgNonce; + + /// @custom:semver 1.0.0 + string public constant version = "1.0.0"; + + /// @notice Emitted whenever a message is sent to the other chain. + /// @param data Encoded data of the message that was sent. + event SentMessage(bytes data) anonymous; + + /// @notice Emitted whenever a message is successfully relayed on this chain. + /// @param msgHash Hash of the message that was relayed. + event RelayedMessage(bytes32 indexed msgHash); + + /// @notice Emitted whenever a message fails to be relayed on this chain. + /// @param msgHash Hash of the message that failed to be relayed. + event FailedRelayedMessage(bytes32 indexed msgHash); + + /// @notice Enforces that cross domain message sender and source are set. Reverts if not. + /// This is leveraged to differentiate between 0 and nil at tstorage slots. + modifier notEntered() { + assembly { + if eq(tload(ENTERED_SLOT), 0) { + mstore(0x00, 0xbca35af6) // 0xbca35af6 is the 4-byte selector of "NotEntered()" + revert(0x1C, 0x04) + } + } + _; + } + + /// @notice Retrieves the sender of the current cross domain message. If not entered, reverts. + /// @return _sender Address of the sender of the current cross domain message. + function crossDomainMessageSender() external view notEntered returns (address _sender) { + assembly { + _sender := tload(CROSS_DOMAIN_MESSAGE_SENDER_SLOT) + } + } + + /// @notice Retrieves the source of the current cross domain message. If not entered, reverts. + /// @return _source Chain ID of the source of the current cross domain message. + function crossDomainMessageSource() external view notEntered returns (uint256 _source) { + assembly { + _source := tload(CROSS_DOMAIN_MESSAGE_SOURCE_SLOT) + } + } + + /// @notice Retrieves the next message nonce. Message version will be added to the upper two + /// bytes of the message nonce. Message version allows us to treat messages as having + /// different structures. + /// @return Nonce of the next message to be sent, with added message version. + function messageNonce() public view returns (uint256) { + return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION); + } + + /// @notice Sends a message to some target address on a destination chain. Note that if the call + /// always reverts, then the message will be unrelayable, and any ETH sent will be + /// permanently locked. The same will occur if the target on the other chain is + /// considered unsafe (see the _isUnsafeTarget() function). + /// @param _destination Chain ID of the destination chain. + /// @param _target Target contract or wallet address. + /// @param _message Message to trigger the target address with. + function sendMessage(uint256 _destination, address _target, bytes calldata _message) external payable { + require(_destination != block.chainid, "L2ToL2CrossDomainMessenger: cannot send message to self"); + + bytes memory data = abi.encodeCall( + L2ToL2CrossDomainMessenger.relayMessage, + (_destination, block.chainid, messageNonce(), msg.sender, _target, _message) + ); + emit SentMessage(data); + msgNonce++; + } + + /// @notice Relays a message that was sent by the other CrossDomainMessenger contract. Can only + /// be executed via cross-chain call from the other messenger OR if the message was + /// already received once and is currently being replayed. + /// @param _destination Chain ID of the destination chain. + /// @param _source Chain ID of the source chain. + /// @param _nonce Nonce of the message being relayed. + /// @param _sender Address of the user who sent the message. + /// @param _target Address that the message is targeted at. + /// @param _message Message to send to the target. + function relayMessage( + uint256 _destination, + uint256 _source, + uint256 _nonce, + address _sender, + address _target, + bytes memory _message + ) + external + payable + { + require(msg.sender == Predeploys.CROSS_L2_INBOX, "L2ToL2CrossDomainMessenger: sender not CrossL2Inbox"); + require( + CrossL2Inbox(Predeploys.CROSS_L2_INBOX).origin() == address(this), + "L2ToL2CrossDomainMessenger: CrossL2Inbox origin not this contract" + ); + require(_destination == block.chainid, "L2ToL2CrossDomainMessenger: destination not this chain"); + require(_target != Predeploys.CROSS_L2_INBOX, "L2ToL2CrossDomainMessenger: CrossL2Inbox cannot call itself"); + + bytes32 messageHash = keccak256(abi.encode(_destination, _source, _nonce, _sender, _target, _message)); + require(successfulMessages[messageHash] == false, "L2ToL2CrossDomainMessenger: message already relayed"); + + _storeMessageMetadata(_source, _sender); + + bool success = _callWithAllGas(_target, _message); + + if (success) { + successfulMessages[messageHash] = true; + emit RelayedMessage(messageHash); + } else { + emit FailedRelayedMessage(messageHash); + } + } + + /// @notice Stores message data such as sender and source in transient storage. + function _storeMessageMetadata(uint256 _source, address _sender) internal { + assembly { + // update `entered` to non-zero + tstore(ENTERED_SLOT, 1) + + tstore(CROSS_DOMAIN_MESSAGE_SOURCE_SLOT, _source) + tstore(CROSS_DOMAIN_MESSAGE_SENDER_SLOT, _sender) + } + } + + /// @notice Calls the target account with the message payload and all available gas. + function _callWithAllGas(address _target, bytes memory _msg) internal returns (bool _success) { + assembly { + _success := + call( + gas(), // gas + _target, // recipient + callvalue(), // ether value + add(_msg, 32), // inloc + mload(_msg), // inlen + 0, // outloc + 0 // outlen + ) + } + } +} diff --git a/packages/contracts-bedrock/src/libraries/Predeploys.sol b/packages/contracts-bedrock/src/libraries/Predeploys.sol index 4e082b9a30ed1..3663ca316413f 100644 --- a/packages/contracts-bedrock/src/libraries/Predeploys.sol +++ b/packages/contracts-bedrock/src/libraries/Predeploys.sol @@ -111,6 +111,9 @@ library Predeploys { /// @notice Address of the EntryPoint predeploy. address internal constant EntryPoint = 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789; + /// @notice Address of the L2ToL2CrossDomainMessenger predeploy. + address internal constant L2_TO_L2_CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000023; + /// @notice Address of the CrossL2Inbox predeploy. address internal constant CROSS_L2_INBOX = 0x4200000000000000000000000000000000000022; } diff --git a/packages/contracts-bedrock/test/L2/L2ToL2CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L2/L2ToL2CrossDomainMessenger.t.sol new file mode 100644 index 0000000000000..5e2c9ea914022 --- /dev/null +++ b/packages/contracts-bedrock/test/L2/L2ToL2CrossDomainMessenger.t.sol @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +// Testing utilities +import { Test } from "forge-std/Test.sol"; +import { Reverter } from "test/mocks/Callers.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; + +// Target contract +import { CrossL2Inbox } from "src/L2/CrossL2Inbox.sol"; +import { L2ToL2CrossDomainMessenger, NotEntered } from "src/L2/L2ToL2CrossDomainMessenger.sol"; + +contract L2ToL2CrossDomainMessengerTest is Test { + /// @dev L2ToL2CrossDomainMessenger contract instance. + L2ToL2CrossDomainMessenger l2ToL2CrossDomainMessenger; + + /// @dev Sets up the test suite. + function setUp() public { + vm.etch(Predeploys.CROSS_L2_INBOX, address(new CrossL2Inbox()).code); + l2ToL2CrossDomainMessenger = new L2ToL2CrossDomainMessenger(); + } + + /// @dev Tests the `sendMessage` function. + function testFuzz_sendMessage_succeeds( + uint256 _destination, + address _target, + bytes memory _message, + uint256 _value + ) + external + { + vm.assume(_destination != block.chainid); + + uint256 messageNoncePre = l2ToL2CrossDomainMessenger.messageNonce(); + + vm.deal(address(this), _value); + + vm.expectEmit(address(l2ToL2CrossDomainMessenger)); + emit L2ToL2CrossDomainMessenger.SentMessage( + abi.encodeWithSelector( + L2ToL2CrossDomainMessenger.relayMessage.selector, + _destination, + block.chainid, + 0, + address(this), + _target, + _message + ) + ); + + l2ToL2CrossDomainMessenger.sendMessage{ value: _value }({ + _destination: _destination, + _target: _target, + _message: _message + }); + + assertEq(l2ToL2CrossDomainMessenger.messageNonce(), messageNoncePre + 1); + } + + /// @dev Tests that the `sendMessage` function fails when the destination is the same as the source. + function test_sendMessage_toSelf_fails() external { + vm.expectRevert("L2ToL2CrossDomainMessenger: cannot send message to self"); + l2ToL2CrossDomainMessenger.sendMessage({ + _destination: block.chainid, + _target: address(0x1234), + _message: hex"1234" + }); + } + + /// @dev Tests the `relayMessage` function. + function testFuzz_relayMessage_succeeds( + uint256 _source, + uint256 _nonce, + address _sender, + address _target, + bytes memory _message, + uint256 _value + ) + external + { + vm.assume(_target.code.length == 0); + + vm.mockCall({ + callee: Predeploys.CROSS_L2_INBOX, + data: abi.encodeWithSelector(CrossL2Inbox.origin.selector), + returnData: abi.encode(address(l2ToL2CrossDomainMessenger)) + }); + + vm.expectEmit(address(l2ToL2CrossDomainMessenger)); + emit L2ToL2CrossDomainMessenger.RelayedMessage( + keccak256(abi.encode(block.chainid, _source, _nonce, _sender, _target, _message)) + ); + + vm.deal(Predeploys.CROSS_L2_INBOX, _value); + + vm.expectCall({ callee: _target, msgValue: _value, data: _message }); + + vm.prank(Predeploys.CROSS_L2_INBOX); + l2ToL2CrossDomainMessenger.relayMessage{ value: _value }({ + _destination: block.chainid, + _source: _source, + _nonce: _nonce, + _sender: _sender, + _target: _target, + _message: _message + }); + + assertEq(l2ToL2CrossDomainMessenger.crossDomainMessageSender(), _sender); + assertEq(l2ToL2CrossDomainMessenger.crossDomainMessageSource(), _source); + } + + /// @dev Tests that the `relayMessage` function fails when the sender is not the CrossL2Inbox contract. + function test_relayMessage_senderNotCrossL2Inbox_fails() external { + vm.expectRevert("L2ToL2CrossDomainMessenger: sender not CrossL2Inbox"); + l2ToL2CrossDomainMessenger.relayMessage({ + _destination: block.chainid, + _source: block.chainid, + _nonce: 0, + _sender: address(0x1234), + _target: address(0), + _message: hex"1234" + }); + } + + /// @dev Tests that the `relayMessage` function fails when the CrossL2Inbox origin is not this contract. + function test_relayMessage_crossL2InboxOriginNotThisContract_fails() external { + vm.mockCall({ + callee: Predeploys.CROSS_L2_INBOX, + data: abi.encodeWithSelector(CrossL2Inbox.origin.selector), + returnData: abi.encode(address(0)) + }); + + vm.prank(Predeploys.CROSS_L2_INBOX); + vm.expectRevert("L2ToL2CrossDomainMessenger: CrossL2Inbox origin not this contract"); + l2ToL2CrossDomainMessenger.relayMessage({ + _destination: block.chainid, + _source: block.chainid, + _nonce: 0, + _sender: address(0x1234), + _target: address(0xabcd), + _message: hex"1234" + }); + } + + /// @dev Tests that the `relayMessage` function fails when the destination is not this chain. + function test_relayMessage_destinationNotThisChain_fails() external { + vm.mockCall({ + callee: Predeploys.CROSS_L2_INBOX, + data: abi.encodeWithSelector(CrossL2Inbox.origin.selector), + returnData: abi.encode(address(l2ToL2CrossDomainMessenger)) + }); + + vm.prank(Predeploys.CROSS_L2_INBOX); + vm.expectRevert("L2ToL2CrossDomainMessenger: destination not this chain"); + l2ToL2CrossDomainMessenger.relayMessage(0, block.chainid, 0, address(0x1234), address(0xabcd), hex"1234"); + } + + /// @dev Tests that the `relayMessage` function fails when the target is the CrossL2Inbox contract. + function test_relayMessage_crossL2InboxCannotCallItself_fails() external { + vm.mockCall({ + callee: Predeploys.CROSS_L2_INBOX, + data: abi.encodeWithSelector(CrossL2Inbox.origin.selector), + returnData: abi.encode(address(l2ToL2CrossDomainMessenger)) + }); + + vm.prank(Predeploys.CROSS_L2_INBOX); + vm.expectRevert("L2ToL2CrossDomainMessenger: CrossL2Inbox cannot call itself"); + l2ToL2CrossDomainMessenger.relayMessage( + block.chainid, block.chainid, 0, address(0x1234), Predeploys.CROSS_L2_INBOX, hex"1234" + ); + } + + /// @dev Tests that the `relayMessage` function fails when the message has already been relayed. + function test_relayMessage_messageAlreadyRelayed_fails() external { + vm.mockCall({ + callee: Predeploys.CROSS_L2_INBOX, + data: abi.encodeWithSelector(CrossL2Inbox.origin.selector), + returnData: abi.encode(address(l2ToL2CrossDomainMessenger)) + }); + + // First call should succeed + vm.prank(Predeploys.CROSS_L2_INBOX); + l2ToL2CrossDomainMessenger.relayMessage({ + _destination: block.chainid, + _source: block.chainid, + _nonce: 0, + _sender: address(0x1234), + _target: address(0xabcd), + _message: hex"1234" + }); + + // Second call should fail + vm.prank(Predeploys.CROSS_L2_INBOX); + vm.expectRevert("L2ToL2CrossDomainMessenger: message already relayed"); + l2ToL2CrossDomainMessenger.relayMessage({ + _destination: block.chainid, + _source: block.chainid, + _nonce: 0, + _sender: address(0x1234), + _target: address(0xabcd), + _message: hex"1234" + }); + } + + /// @dev Tests that the `relayMessage` function fails when the target call fails. + function test_relayMessage_targetCallFails() external { + vm.mockCall({ + callee: Predeploys.CROSS_L2_INBOX, + data: abi.encodeWithSelector(CrossL2Inbox.origin.selector), + returnData: abi.encode(address(l2ToL2CrossDomainMessenger)) + }); + + // Target call should fail, so we etch a Reverter() to the target contract + vm.etch(address(0xabcd), address(new Reverter()).code); + + vm.prank(Predeploys.CROSS_L2_INBOX); + vm.expectEmit(address(l2ToL2CrossDomainMessenger)); + emit L2ToL2CrossDomainMessenger.FailedRelayedMessage( + keccak256(abi.encode(block.chainid, block.chainid, 0, address(0x1234), address(0xabcd), hex"1234")) + ); + l2ToL2CrossDomainMessenger.relayMessage({ + _destination: block.chainid, + _source: block.chainid, + _nonce: 0, + _sender: address(0x1234), + _target: address(0xabcd), + _message: hex"1234" + }); + } + + /// @dev Tests that `crossDomainMessageSender` reverts when not entered. + function test_crossDomainMessageSender_notEntered_fails() external { + vm.expectRevert(NotEntered.selector); + l2ToL2CrossDomainMessenger.crossDomainMessageSender(); + } + + /// @dev Tests that `crossDomainMessageSource` reverts when not entered. + function test_crossDomainMessageSource_notEntered_fails() external { + vm.expectRevert(NotEntered.selector); + l2ToL2CrossDomainMessenger.crossDomainMessageSource(); + } +} diff --git a/packages/contracts-bedrock/test/Predeploys.t.sol b/packages/contracts-bedrock/test/Predeploys.t.sol index 6e26c6dea4836..6cafcf2c9878c 100644 --- a/packages/contracts-bedrock/test/Predeploys.t.sol +++ b/packages/contracts-bedrock/test/Predeploys.t.sol @@ -33,7 +33,7 @@ contract PredeploysTest is CommonTest { || _addr == Predeploys.L1_BLOCK_NUMBER || _addr == Predeploys.LEGACY_MESSAGE_PASSER || _addr == Predeploys.PROXY_ADMIN || _addr == Predeploys.BASE_FEE_VAULT || _addr == Predeploys.L1_FEE_VAULT || _addr == Predeploys.GOVERNANCE_TOKEN || _addr == Predeploys.SCHEMA_REGISTRY || _addr == Predeploys.EAS - || _addr == Predeploys.CROSS_L2_INBOX; + || _addr == Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER || _addr == Predeploys.CROSS_L2_INBOX; } /// @dev Returns true if the adress is not proxied. diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 89905c6b57d84..cb4a39db22469 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -35,6 +35,7 @@ import { Executables } from "scripts/Executables.sol"; import { Vm } from "forge-std/Vm.sol"; import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { DataAvailabilityChallenge } from "src/L1/DataAvailabilityChallenge.sol"; +import { IL2ToL2CrossDomainMessenger } from "src/L2/IL2ToL2CrossDomainMessenger.sol"; import { ICrossL2Inbox } from "src/L2/ICrossL2Inbox.sol"; /// @title Setup @@ -80,6 +81,8 @@ contract Setup { L1Block l1Block = L1Block(Predeploys.L1_BLOCK_ATTRIBUTES); LegacyMessagePasser legacyMessagePasser = LegacyMessagePasser(Predeploys.LEGACY_MESSAGE_PASSER); GovernanceToken governanceToken = GovernanceToken(Predeploys.GOVERNANCE_TOKEN); + IL2ToL2CrossDomainMessenger l2ToL2CrossDomainMessenger = + IL2ToL2CrossDomainMessenger(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER); ICrossL2Inbox crossL2Inbox = ICrossL2Inbox(Predeploys.CROSS_L2_INBOX); /// @dev Deploys the Deploy contract without including its bytecode in the bytecode @@ -190,6 +193,7 @@ contract Setup { vm.label(Predeploys.GOVERNANCE_TOKEN, "GovernanceToken"); vm.label(Predeploys.EAS, "EAS"); vm.label(Predeploys.SCHEMA_REGISTRY, "SchemaRegistry"); + vm.label(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER, "L2ToL2CrossDomainMessenger"); vm.label(Predeploys.CROSS_L2_INBOX, "CrossL2Inbox"); } } diff --git a/packages/sdk/src/utils/contracts.ts b/packages/sdk/src/utils/contracts.ts index c17b7b7b528ba..34c3dabe36642 100644 --- a/packages/sdk/src/utils/contracts.ts +++ b/packages/sdk/src/utils/contracts.ts @@ -17,6 +17,7 @@ import gasPriceOracle from '@eth-optimism/contracts-bedrock/forge-artifacts/GasP import disputeGameFactory from '@eth-optimism/contracts-bedrock/forge-artifacts/DisputeGameFactory.sol/DisputeGameFactory.json' import optimismPortal2 from '@eth-optimism/contracts-bedrock/forge-artifacts/OptimismPortal2.sol/OptimismPortal2.json' import faultDisputeGame from '@eth-optimism/contracts-bedrock/forge-artifacts/FaultDisputeGame.sol/FaultDisputeGame.json' +import l2ToL2CrossDomainMessenger from '@eth-optimism/contracts-bedrock/forge-artifacts/L2ToL2CrossDomainMessenger.sol/L2ToL2CrossDomainMessenger.json' import crossL2Inbox from '@eth-optimism/contracts-bedrock/forge-artifacts/CrossL2Inbox.sol/CrossL2Inbox.json' import { toAddress } from './coercion' @@ -109,6 +110,8 @@ export const getContractInterfaceBedrock = ( break case 'FaultDisputeGame': artifact = faultDisputeGame + case 'L2ToL2CrossDomainMessenger': + artifact = l2ToL2CrossDomainMessenger case 'CrossL2Inbox': artifact = crossL2Inbox break