From 58215190b711bb031c2f62672a8e7b8763c527f9 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Fri, 13 Dec 2024 12:55:16 -0300 Subject: [PATCH] Add arbitrum bridging and teleport --- bindings/L1Teleporter/L1Teleporter.go | 3714 +++++++++++++++++ .../L2ForwarderFactory/L2ForwarderFactory.go | 1546 +++++++ cmd/arbitrum/bridge.go | 163 + cmd/arbitrum/bridgeCmd.go | 405 ++ cmd/arbitrum/{aribtrum.go => cmd.go} | 45 +- cmd/arbitrum/gas.go | 148 + cmd/arbitrum/helpers.go | 36 + cmd/arbitrum/teleporter.go | 74 + 8 files changed, 6115 insertions(+), 16 deletions(-) create mode 100644 bindings/L1Teleporter/L1Teleporter.go create mode 100644 bindings/L2ForwarderFactory/L2ForwarderFactory.go create mode 100644 cmd/arbitrum/bridgeCmd.go rename cmd/arbitrum/{aribtrum.go => cmd.go} (71%) create mode 100644 cmd/arbitrum/teleporter.go diff --git a/bindings/L1Teleporter/L1Teleporter.go b/bindings/L1Teleporter/L1Teleporter.go new file mode 100644 index 0000000..b3a43b5 --- /dev/null +++ b/bindings/L1Teleporter/L1Teleporter.go @@ -0,0 +1,3714 @@ +// This file was generated by seer: https://github.com/G7DAO/seer. +// seer version: 0.1.3 +// seer command: seer evm generate --package L1Teleporter --cli --struct L1Teleporter +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package L1Teleporter + +import ( + "errors" + "math/big" + "strings" + + "context" + + 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. + "encoding/hex" + "encoding/json" + "fmt" + "os" + "time" + + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/spf13/cobra" + "golang.org/x/term" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// IL1TeleporterRetryableGasCosts is an auto generated low-level Go binding around an user-defined struct. +type IL1TeleporterRetryableGasCosts struct { + L1l2FeeTokenBridgeCost *big.Int + L1l2TokenBridgeCost *big.Int + L2ForwarderFactoryCost *big.Int + L2l3TokenBridgeCost *big.Int +} + +// IL1TeleporterRetryableGasParams is an auto generated low-level Go binding around an user-defined struct. +type IL1TeleporterRetryableGasParams struct { + L2GasPriceBid *big.Int + L3GasPriceBid *big.Int + L2ForwarderFactoryGasLimit uint64 + L1l2FeeTokenBridgeGasLimit uint64 + L1l2TokenBridgeGasLimit uint64 + L2l3TokenBridgeGasLimit uint64 + L2ForwarderFactoryMaxSubmissionCost *big.Int + L1l2FeeTokenBridgeMaxSubmissionCost *big.Int + L1l2TokenBridgeMaxSubmissionCost *big.Int + L2l3TokenBridgeMaxSubmissionCost *big.Int +} + +// IL1TeleporterTeleportParams is an auto generated low-level Go binding around an user-defined struct. +type IL1TeleporterTeleportParams struct { + L1Token common.Address + L3FeeTokenL1Addr common.Address + L1l2Router common.Address + L2l3RouterOrInbox common.Address + To common.Address + Amount *big.Int + GasParams IL1TeleporterRetryableGasParams + L3CallData []byte +} + +// IL2ForwarderL2ForwarderParams is an auto generated low-level Go binding around an user-defined struct. +type IL2ForwarderL2ForwarderParams struct { + Owner common.Address + L2Token common.Address + L3FeeTokenL2Addr common.Address + RouterOrInbox common.Address + To common.Address + GasLimit *big.Int + GasPriceBid *big.Int + MaxSubmissionCost *big.Int + L3CallData []byte +} + +// L1TeleporterMetaData contains all meta data concerning the L1Teleporter contract. +var L1TeleporterMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l2ForwarderFactory\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2ForwarderImplementation\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_pauser\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"provided\",\"type\":\"uint256\"}],\"name\":\"IncorrectValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"provided\",\"type\":\"uint256\"}],\"name\":\"InsufficientFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTeleportation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonZeroFeeTokenAmount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"l3FeeTokenL1Addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"l1l2Router\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"l2l3RouterOrInbox\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Teleported\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PAUSER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SKIP_FEE_TOKEN_MAGIC_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l3FeeTokenL1Addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1l2Router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l2l3RouterOrInbox\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"l2GasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l3GasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"l2ForwarderFactoryGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1l2FeeTokenBridgeGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1l2TokenBridgeGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l2l3TokenBridgeGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"l2ForwarderFactoryMaxSubmissionCost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l1l2FeeTokenBridgeMaxSubmissionCost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l1l2TokenBridgeMaxSubmissionCost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l2l3TokenBridgeMaxSubmissionCost\",\"type\":\"uint256\"}],\"internalType\":\"structIL1Teleporter.RetryableGasParams\",\"name\":\"gasParams\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"l3CallData\",\"type\":\"bytes\"}],\"internalType\":\"structIL1Teleporter.TeleportParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"buildL2ForwarderParams\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l3FeeTokenL2Addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"routerOrInbox\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSubmissionCost\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"l3CallData\",\"type\":\"bytes\"}],\"internalType\":\"structIL2Forwarder.L2ForwarderParams\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l3FeeTokenL1Addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1l2Router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l2l3RouterOrInbox\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"l2GasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l3GasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"l2ForwarderFactoryGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1l2FeeTokenBridgeGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1l2TokenBridgeGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l2l3TokenBridgeGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"l2ForwarderFactoryMaxSubmissionCost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l1l2FeeTokenBridgeMaxSubmissionCost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l1l2TokenBridgeMaxSubmissionCost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l2l3TokenBridgeMaxSubmissionCost\",\"type\":\"uint256\"}],\"internalType\":\"structIL1Teleporter.RetryableGasParams\",\"name\":\"gasParams\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"l3CallData\",\"type\":\"bytes\"}],\"internalType\":\"structIL1Teleporter.TeleportParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"determineTypeAndFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"ethAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"enumTeleportationType\",\"name\":\"teleportationType\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"l1l2FeeTokenBridgeCost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l1l2TokenBridgeCost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l2ForwarderFactoryCost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l2l3TokenBridgeCost\",\"type\":\"uint256\"}],\"internalType\":\"structIL1Teleporter.RetryableGasCosts\",\"name\":\"costs\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"routerOrInbox\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"l2ForwarderAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2ForwarderFactory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2ForwarderImplementation\",\"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\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l3FeeTokenL1Addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l1l2Router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l2l3RouterOrInbox\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"l2GasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l3GasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"l2ForwarderFactoryGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1l2FeeTokenBridgeGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1l2TokenBridgeGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l2l3TokenBridgeGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"l2ForwarderFactoryMaxSubmissionCost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l1l2FeeTokenBridgeMaxSubmissionCost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l1l2TokenBridgeMaxSubmissionCost\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"l2l3TokenBridgeMaxSubmissionCost\",\"type\":\"uint256\"}],\"internalType\":\"structIL1Teleporter.RetryableGasParams\",\"name\":\"gasParams\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"l3CallData\",\"type\":\"bytes\"}],\"internalType\":\"structIL1Teleporter.TeleportParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"teleport\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60c06040523480156200001157600080fd5b5060405162002b8938038062002b89833981016040819052620000349162000139565b6000805460ff191681556001600160a01b03808616608052841660a0526200005d908362000093565b620000897f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8262000093565b5050505062000196565b60008281526001602090815260408083206001600160a01b038516845290915290205460ff16620001185760008281526001602081815260408084206001600160a01b0386168086529252808420805460ff19169093179092559051339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45b5050565b80516001600160a01b03811681146200013457600080fd5b919050565b600080600080608085870312156200015057600080fd5b6200015b856200011c565b93506200016b602086016200011c565b92506200017b604086016200011c565b91506200018b606086016200011c565b905092959194509250565b60805160a0516129b8620001d1600039600081816103e50152610dfe01526000818161023601528181610dc2015261129801526129b86000f3fe6080604052600436106101295760003560e01c80638456cb59116100a5578063c238b3d111610074578063e63ab1e911610059578063e63ab1e91461039f578063ec7d4abd146103d3578063fbabf0841461040757600080fd5b8063c238b3d11461034f578063d547741f1461037f57600080fd5b80638456cb59146102aa5780639045f6d4146102bf57806391d14854146102e7578063a217fddf1461033a57600080fd5b80632f2ff15d116100fc578063377f017a116100e1578063377f017a146102245780633f4ba83a1461027d5780635c975abb1461029257600080fd5b80632f2ff15d146101e457806336568abe1461020457600080fd5b806301ffc9a71461012e5780632478a34b14610163578063248a9ca3146101785780632c4e3f9d146101b7575b600080fd5b34801561013a57600080fd5b5061014e610149366004612183565b610427565b60405190151581526020015b60405180910390f35b6101766101713660046121de565b6104c0565b005b34801561018457600080fd5b506101a9610193366004612213565b6000908152600160208190526040909120015490565b60405190815260200161015a565b3480156101c357600080fd5b506101d76101d236600461224e565b610703565b60405161015a919061230e565b3480156101f057600080fd5b506101766101ff366004612404565b610b0c565b34801561021057600080fd5b5061017661021f366004612404565b610b37565b34801561023057600080fd5b506102587f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161015a565b34801561028957600080fd5b50610176610bea565b34801561029e57600080fd5b5060005460ff1661014e565b3480156102b657600080fd5b50610176610c1f565b3480156102cb57600080fd5b5061025873ca040eea1dc95e969d9dc07af75147987c83089781565b3480156102f357600080fd5b5061014e610302366004612404565b600091825260016020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561034657600080fd5b506101a9600081565b34801561035b57600080fd5b5061036f61036a3660046121de565b610c51565b60405161015a9493929190612458565b34801561038b57600080fd5b5061017661039a366004612404565b610d4b565b3480156103ab57600080fd5b506101a97f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b3480156103df57600080fd5b506102587f000000000000000000000000000000000000000000000000000000000000000081565b34801561041357600080fd5b506102586104223660046124d1565b610d71565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806104ba57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6104c8610e62565b6000806000806104d785610c51565b9350935093509350833414610526576040517fb25102da000000000000000000000000000000000000000000000000000000008152600481018590523460248201526044015b60405180910390fd5b600061055461053433610ed1565b6105446080890160608a0161251c565b61042260a08a0160808b0161251c565b9050600183600281111561056a5761056a612429565b036105bf57838660a0013510156105ba576040517fa0d383da0000000000000000000000000000000000000000000000000000000081526004810185905260a0870135602482015260440161051d565b61062f565b60028360028111156105d3576105d3612429565b0361062f57831561062f5761062f6105f1606088016040890161251c565b6106016040890160208a0161251c565b83876106156101408c016101208d01612539565b67ffffffffffffffff1660c08c01356101a08d0135610f13565b61063a8683836111a5565b337f762fcae5372ec0a8b89250dca23af574afcad1e9db4425b0a2d9e8f9e8a64ad0610669602089018961251c565b61067960408a0160208b0161251c565b61068960608b0160408c0161251c565b61069960808c0160608d0161251c565b6106a960a08d0160808e0161251c565b6040805173ffffffffffffffffffffffffffffffffffffffff96871681529486166020860152928516848401529084166060840152909216608082015260a08a8101359082015290519081900360c00190a2505050505050565b6107c0604051806101200160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016000815260200160008152602001606081525090565b60006107d2606085016040860161251c565b73ffffffffffffffffffffffffffffffffffffffff1663a7e28d486107fa602087018761251c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401602060405180830381865afa158015610863573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108879190612563565b9050600080806108b261089d602089018961251c565b6108ad60408a0160208b0161251c565b6113fe565b905060008160028111156108c8576108c8612429565b036108d657600092506109ca565b60018160028111156108ea576108ea612429565b036108f7578392506109ca565b610907606088016040890161251c565b73ffffffffffffffffffffffffffffffffffffffff1663a7e28d4861093260408a0160208b0161251c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401602060405180830381865afa15801561099b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bf9190612563565b92506101e087013591505b6040518061012001604052806109df88610ed1565b73ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff168152602001886060016020810190610a45919061251c565b73ffffffffffffffffffffffffffffffffffffffff168152602001610a7060a08a0160808b0161251c565b73ffffffffffffffffffffffffffffffffffffffff168152602001610a9d6101808a016101608b01612539565b67ffffffffffffffff16815260e0890135602082015260408101849052606001610acb6102008a018a612580565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050915250979650505050505050565b60008281526001602081905260409091200154610b28816114b3565b610b3283836114bd565b505050565b73ffffffffffffffffffffffffffffffffffffffff81163314610bdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840161051d565b610be6828261157c565b5050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610c14816114b3565b610c1c611637565b50565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610c49816114b3565b610c1c6116b4565b6000806000610c816040518060800160405280600081526020016000815260200160008152602001600081525090565b610c8a8561170f565b610c968560c0016117fa565b9050610cb8610ca8602087018761251c565b6108ad604088016020890161251c565b915080604001518160200151610cce919061261b565b93506000826002811115610ce457610ce4612429565b03610cff576060810151610cf8908561261b565b9350610d44565b6001826002811115610d1357610d13612429565b03610d245780606001519250610d44565b606081015115610d44578051610d3a908561261b565b9350806060015192505b9193509193565b60008281526001602081905260409091200154610d67816114b3565b610b32838361157c565b6040805173ffffffffffffffffffffffffffffffffffffffff8581166020808401919091528582168385015290841660608084019190915283518084039091018152608083019384905280519101207f000000000000000000000000000000000000000000000000000000000000000060b88301526f5af43d82803e903d91602b57fd5bf3ff60a48301527f00000000000000000000000000000000000000000000000000000000000000006094830152733d602d80600a3d3981f3363d3d373d3d3d363d7390925260d88101919091526037608c82012060f8820152605560c3909101206000905b949350505050565b60005460ff1615610ecf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161051d565b565b6000808273ffffffffffffffffffffffffffffffffffffffff163b11610ef757816104ba565b73111100000000000000000000000000000000111182016104ba565b610f3573ffffffffffffffffffffffffffffffffffffffff8716333087611910565b6040517fbda009fe00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301526000919089169063bda009fe90602401602060405180830381865afa158015610fa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc99190612563565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff80831660248301529192509088169063dd62ed3e90604401602060405180830381865afa15801561103f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611063919061262e565b6000036110ab576110ab73ffffffffffffffffffffffffffffffffffffffff8816827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6119f2565b73ffffffffffffffffffffffffffffffffffffffff8816634fb1a07b836110d28688612647565b6110dc919061261b565b89898a8a8a8a8a6040518060200160405280600081525060405160200161110492919061265e565b6040516020818303038152906040526040518963ffffffff1660e01b81526004016111359796959493929190612677565b60006040518083038185885af1158015611153573d6000803e3d6000fd5b50505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261119a9190810190612706565b505050505050505050565b6111f76111b8606085016040860161251c565b6111c5602086018661251c565b8360a08701356111dd61016089016101408a01612539565b67ffffffffffffffff1660c08901356101c08a0135610f13565b6000611209606085016040860161251c565b73ffffffffffffffffffffffffffffffffffffffff1663fb0e722b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611253573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112779190612563565b90508073ffffffffffffffffffffffffffffffffffffffff1663679b6ded477f00000000000000000000000000000000000000000000000000000000000000008660400151476112c791906127c6565b61018089013587806112e16101208d016101008e01612539565b60c08d01356112f08e33610703565b604051602401611300919061230e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f5b65a6a400000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e08c901b1681526113b49897969594939291906004016127d9565b60206040518083038185885af11580156113d2573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906113f7919061262e565b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff831661144d576040517f83fe0edc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216611470575060006104ba565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036114ab575060016104ba565b5060026104ba565b610c1c8133611b74565b600082815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610be657600082815260016020818152604080842073ffffffffffffffffffffffffffffffffffffffff8616808652925280842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169093179092559051339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b600082815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1615610be657600082815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b61163f611c2e565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6116bc610e62565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861168a3390565b73ca040eea1dc95e969d9dc07af75147987c830897611734604083016020840161251c565b73ffffffffffffffffffffffffffffffffffffffff161480156117c357506101e08101351515806117805750600061177461018083016101608401612539565b67ffffffffffffffff16115b806117a65750600061179a61014083016101208401612539565b67ffffffffffffffff16115b806117b557506101a081013515155b806117c3575060e081013515155b15610c1c576040517f870e439500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118256040518060800160405280600081526020016000815260200160008152602001600081525090565b81356118376080840160608501612539565b67ffffffffffffffff1661184b9190612647565b6118599060e084013561261b565b8152813561186d60a0840160808501612539565b67ffffffffffffffff166118819190612647565b6118909061010084013561261b565b602082015281356118a76060840160408501612539565b67ffffffffffffffff166118bb9190612647565b6118c99060c084013561261b565b604082015260208201356118e360c0840160a08501612539565b67ffffffffffffffff166118f79190612647565b6119069061012084013561261b565b6060820152919050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526119ec9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611c9a565b50505050565b801580611a9257506040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611a6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a90919061262e565b155b611b1e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606482015260840161051d565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610b329084907f095ea7b3000000000000000000000000000000000000000000000000000000009060640161196a565b600082815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610be657611bb481611da9565b611bbf836020611dc8565b604051602001611bd092919061284c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a000000000000000000000000000000000000000000000000000000000825261051d916004016128cd565b60005460ff16610ecf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161051d565b6000611cfc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166120129092919063ffffffff16565b9050805160001480611d1d575080806020019051810190611d1d91906128e0565b610b32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161051d565b60606104ba73ffffffffffffffffffffffffffffffffffffffff831660145b60606000611dd7836002612647565b611de290600261261b565b67ffffffffffffffff811115611dfa57611dfa6126d7565b6040519080825280601f01601f191660200182016040528015611e24576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611e5b57611e5b612902565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611ebe57611ebe612902565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611efa846002612647565b611f0590600161261b565b90505b6001811115611fa2577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611f4657611f46612902565b1a60f81b828281518110611f5c57611f5c612902565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93611f9b81612931565b9050611f08565b50831561200b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161051d565b9392505050565b6060610e5a8484600085856000808673ffffffffffffffffffffffffffffffffffffffff1685876040516120469190612966565b60006040518083038185875af1925050503d8060008114612083576040519150601f19603f3d011682016040523d82523d6000602084013e612088565b606091505b5091509150612099878383876120a4565b979650505050505050565b6060831561213a5782516000036121335773ffffffffffffffffffffffffffffffffffffffff85163b612133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161051d565b5081610e5a565b610e5a838381511561214f5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161051d91906128cd565b60006020828403121561219557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461200b57600080fd5b600061022082840312156121d857600080fd5b50919050565b6000602082840312156121f057600080fd5b813567ffffffffffffffff81111561220757600080fd5b610e5a848285016121c5565b60006020828403121561222557600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610c1c57600080fd5b6000806040838503121561226157600080fd5b823567ffffffffffffffff81111561227857600080fd5b612284858286016121c5565b92505060208301356122958161222c565b809150509250929050565b60005b838110156122bb5781810151838201526020016122a3565b50506000910152565b600081518084526122dc8160208601602086016122a0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815261233560208201835173ffffffffffffffffffffffffffffffffffffffff169052565b6000602083015161235e604084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604083015173ffffffffffffffffffffffffffffffffffffffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015173ffffffffffffffffffffffffffffffffffffffff811660a08401525060a083015160c083015260c083015160e083015260e0830151610100818185015280850151915050610120808185015250610e5a6101408401826122c4565b6000806040838503121561241757600080fd5b8235915060208301356122958161222c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8481526020810184905260e081016003841061249d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8360408301528251606083015260208301516080830152604083015160a0830152606083015160c083015295945050505050565b6000806000606084860312156124e657600080fd5b83356124f18161222c565b925060208401356125018161222c565b915060408401356125118161222c565b809150509250925092565b60006020828403121561252e57600080fd5b813561200b8161222c565b60006020828403121561254b57600080fd5b813567ffffffffffffffff8116811461200b57600080fd5b60006020828403121561257557600080fd5b815161200b8161222c565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126125b557600080fd5b83018035915067ffffffffffffffff8211156125d057600080fd5b6020019150368190038213156125e557600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104ba576104ba6125ec565b60006020828403121561264057600080fd5b5051919050565b80820281158282048414176104ba576104ba6125ec565b828152604060208201526000610e5a60408301846122c4565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401528088166040840152508560608301528460808301528360a083015260e060c08301526126ca60e08301846122c4565b9998505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561271857600080fd5b815167ffffffffffffffff8082111561273057600080fd5b818401915084601f83011261274457600080fd5b815181811115612756576127566126d7565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561279c5761279c6126d7565b816040528281528760208487010111156127b557600080fd5b6120998360208301602088016122a0565b818103818111156104ba576104ba6125ec565b600061010073ffffffffffffffffffffffffffffffffffffffff808c1684528a6020850152896040850152808916606085015280881660808501525067ffffffffffffffff861660a08401528460c08401528060e084015261283d818401856122c4565b9b9a5050505050505050505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516128848160178501602088016122a0565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516128c18160288401602088016122a0565b01602801949350505050565b60208152600061200b60208301846122c4565b6000602082840312156128f257600080fd5b8151801515811461200b57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081612940576129406125ec565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b600082516129788184602087016122a0565b919091019291505056fea2646970667358221220bc9abe1eee394c38f986ac2ac45c53b3b7f60abb5238d8b0fc45e9a5b647849c64736f6c63430008170033", +} + +// L1TeleporterABI is the input ABI used to generate the binding from. +// Deprecated: Use L1TeleporterMetaData.ABI instead. +var L1TeleporterABI = L1TeleporterMetaData.ABI + +// L1TeleporterBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use L1TeleporterMetaData.Bin instead. +var L1TeleporterBin = L1TeleporterMetaData.Bin + +// DeployL1Teleporter deploys a new Ethereum contract, binding an instance of L1Teleporter to it. +func DeployL1Teleporter(auth *bind.TransactOpts, backend bind.ContractBackend, _l2ForwarderFactory common.Address, _l2ForwarderImplementation common.Address, _admin common.Address, _pauser common.Address) (common.Address, *types.Transaction, *L1Teleporter, error) { + parsed, err := L1TeleporterMetaData.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(L1TeleporterBin), backend, _l2ForwarderFactory, _l2ForwarderImplementation, _admin, _pauser) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &L1Teleporter{L1TeleporterCaller: L1TeleporterCaller{contract: contract}, L1TeleporterTransactor: L1TeleporterTransactor{contract: contract}, L1TeleporterFilterer: L1TeleporterFilterer{contract: contract}}, nil +} + +// L1Teleporter is an auto generated Go binding around an Ethereum contract. +type L1Teleporter struct { + L1TeleporterCaller // Read-only binding to the contract + L1TeleporterTransactor // Write-only binding to the contract + L1TeleporterFilterer // Log filterer for contract events +} + +// L1TeleporterCaller is an auto generated read-only Go binding around an Ethereum contract. +type L1TeleporterCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// L1TeleporterTransactor is an auto generated write-only Go binding around an Ethereum contract. +type L1TeleporterTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// L1TeleporterFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type L1TeleporterFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// L1TeleporterSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type L1TeleporterSession struct { + Contract *L1Teleporter // 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 +} + +// L1TeleporterCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type L1TeleporterCallerSession struct { + Contract *L1TeleporterCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// L1TeleporterTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type L1TeleporterTransactorSession struct { + Contract *L1TeleporterTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// L1TeleporterRaw is an auto generated low-level Go binding around an Ethereum contract. +type L1TeleporterRaw struct { + Contract *L1Teleporter // Generic contract binding to access the raw methods on +} + +// L1TeleporterCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type L1TeleporterCallerRaw struct { + Contract *L1TeleporterCaller // Generic read-only contract binding to access the raw methods on +} + +// L1TeleporterTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type L1TeleporterTransactorRaw struct { + Contract *L1TeleporterTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewL1Teleporter creates a new instance of L1Teleporter, bound to a specific deployed contract. +func NewL1Teleporter(address common.Address, backend bind.ContractBackend) (*L1Teleporter, error) { + contract, err := bindL1Teleporter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &L1Teleporter{L1TeleporterCaller: L1TeleporterCaller{contract: contract}, L1TeleporterTransactor: L1TeleporterTransactor{contract: contract}, L1TeleporterFilterer: L1TeleporterFilterer{contract: contract}}, nil +} + +// NewL1TeleporterCaller creates a new read-only instance of L1Teleporter, bound to a specific deployed contract. +func NewL1TeleporterCaller(address common.Address, caller bind.ContractCaller) (*L1TeleporterCaller, error) { + contract, err := bindL1Teleporter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &L1TeleporterCaller{contract: contract}, nil +} + +// NewL1TeleporterTransactor creates a new write-only instance of L1Teleporter, bound to a specific deployed contract. +func NewL1TeleporterTransactor(address common.Address, transactor bind.ContractTransactor) (*L1TeleporterTransactor, error) { + contract, err := bindL1Teleporter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &L1TeleporterTransactor{contract: contract}, nil +} + +// NewL1TeleporterFilterer creates a new log filterer instance of L1Teleporter, bound to a specific deployed contract. +func NewL1TeleporterFilterer(address common.Address, filterer bind.ContractFilterer) (*L1TeleporterFilterer, error) { + contract, err := bindL1Teleporter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &L1TeleporterFilterer{contract: contract}, nil +} + +// bindL1Teleporter binds a generic wrapper to an already deployed contract. +func bindL1Teleporter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := L1TeleporterMetaData.GetAbi() + 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 (_L1Teleporter *L1TeleporterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _L1Teleporter.Contract.L1TeleporterCaller.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 (_L1Teleporter *L1TeleporterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _L1Teleporter.Contract.L1TeleporterTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_L1Teleporter *L1TeleporterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _L1Teleporter.Contract.L1TeleporterTransactor.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 (_L1Teleporter *L1TeleporterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _L1Teleporter.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 (_L1Teleporter *L1TeleporterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _L1Teleporter.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_L1Teleporter *L1TeleporterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _L1Teleporter.Contract.contract.Transact(opts, method, params...) +} + +// DEFAULTADMINROLE is a free data retrieval call binding the contract method 0xa217fddf. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (_L1Teleporter *L1TeleporterCaller) DEFAULTADMINROLE(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _L1Teleporter.contract.Call(opts, &out, "DEFAULT_ADMIN_ROLE") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// DEFAULTADMINROLE is a free data retrieval call binding the contract method 0xa217fddf. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (_L1Teleporter *L1TeleporterSession) DEFAULTADMINROLE() ([32]byte, error) { + return _L1Teleporter.Contract.DEFAULTADMINROLE(&_L1Teleporter.CallOpts) +} + +// DEFAULTADMINROLE is a free data retrieval call binding the contract method 0xa217fddf. +// +// Solidity: function DEFAULT_ADMIN_ROLE() view returns(bytes32) +func (_L1Teleporter *L1TeleporterCallerSession) DEFAULTADMINROLE() ([32]byte, error) { + return _L1Teleporter.Contract.DEFAULTADMINROLE(&_L1Teleporter.CallOpts) +} + +// PAUSERROLE is a free data retrieval call binding the contract method 0xe63ab1e9. +// +// Solidity: function PAUSER_ROLE() view returns(bytes32) +func (_L1Teleporter *L1TeleporterCaller) PAUSERROLE(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _L1Teleporter.contract.Call(opts, &out, "PAUSER_ROLE") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// PAUSERROLE is a free data retrieval call binding the contract method 0xe63ab1e9. +// +// Solidity: function PAUSER_ROLE() view returns(bytes32) +func (_L1Teleporter *L1TeleporterSession) PAUSERROLE() ([32]byte, error) { + return _L1Teleporter.Contract.PAUSERROLE(&_L1Teleporter.CallOpts) +} + +// PAUSERROLE is a free data retrieval call binding the contract method 0xe63ab1e9. +// +// Solidity: function PAUSER_ROLE() view returns(bytes32) +func (_L1Teleporter *L1TeleporterCallerSession) PAUSERROLE() ([32]byte, error) { + return _L1Teleporter.Contract.PAUSERROLE(&_L1Teleporter.CallOpts) +} + +// SKIPFEETOKENMAGICADDRESS is a free data retrieval call binding the contract method 0x9045f6d4. +// +// Solidity: function SKIP_FEE_TOKEN_MAGIC_ADDRESS() view returns(address) +func (_L1Teleporter *L1TeleporterCaller) SKIPFEETOKENMAGICADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _L1Teleporter.contract.Call(opts, &out, "SKIP_FEE_TOKEN_MAGIC_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SKIPFEETOKENMAGICADDRESS is a free data retrieval call binding the contract method 0x9045f6d4. +// +// Solidity: function SKIP_FEE_TOKEN_MAGIC_ADDRESS() view returns(address) +func (_L1Teleporter *L1TeleporterSession) SKIPFEETOKENMAGICADDRESS() (common.Address, error) { + return _L1Teleporter.Contract.SKIPFEETOKENMAGICADDRESS(&_L1Teleporter.CallOpts) +} + +// SKIPFEETOKENMAGICADDRESS is a free data retrieval call binding the contract method 0x9045f6d4. +// +// Solidity: function SKIP_FEE_TOKEN_MAGIC_ADDRESS() view returns(address) +func (_L1Teleporter *L1TeleporterCallerSession) SKIPFEETOKENMAGICADDRESS() (common.Address, error) { + return _L1Teleporter.Contract.SKIPFEETOKENMAGICADDRESS(&_L1Teleporter.CallOpts) +} + +// BuildL2ForwarderParams is a free data retrieval call binding the contract method 0x2c4e3f9d. +// +// Solidity: function buildL2ForwarderParams((address,address,address,address,address,uint256,(uint256,uint256,uint64,uint64,uint64,uint64,uint256,uint256,uint256,uint256),bytes) params, address caller) view returns((address,address,address,address,address,uint256,uint256,uint256,bytes)) +func (_L1Teleporter *L1TeleporterCaller) BuildL2ForwarderParams(opts *bind.CallOpts, params IL1TeleporterTeleportParams, caller common.Address) (IL2ForwarderL2ForwarderParams, error) { + var out []interface{} + err := _L1Teleporter.contract.Call(opts, &out, "buildL2ForwarderParams", params, caller) + + if err != nil { + return *new(IL2ForwarderL2ForwarderParams), err + } + + out0 := *abi.ConvertType(out[0], new(IL2ForwarderL2ForwarderParams)).(*IL2ForwarderL2ForwarderParams) + + return out0, err + +} + +// BuildL2ForwarderParams is a free data retrieval call binding the contract method 0x2c4e3f9d. +// +// Solidity: function buildL2ForwarderParams((address,address,address,address,address,uint256,(uint256,uint256,uint64,uint64,uint64,uint64,uint256,uint256,uint256,uint256),bytes) params, address caller) view returns((address,address,address,address,address,uint256,uint256,uint256,bytes)) +func (_L1Teleporter *L1TeleporterSession) BuildL2ForwarderParams(params IL1TeleporterTeleportParams, caller common.Address) (IL2ForwarderL2ForwarderParams, error) { + return _L1Teleporter.Contract.BuildL2ForwarderParams(&_L1Teleporter.CallOpts, params, caller) +} + +// BuildL2ForwarderParams is a free data retrieval call binding the contract method 0x2c4e3f9d. +// +// Solidity: function buildL2ForwarderParams((address,address,address,address,address,uint256,(uint256,uint256,uint64,uint64,uint64,uint64,uint256,uint256,uint256,uint256),bytes) params, address caller) view returns((address,address,address,address,address,uint256,uint256,uint256,bytes)) +func (_L1Teleporter *L1TeleporterCallerSession) BuildL2ForwarderParams(params IL1TeleporterTeleportParams, caller common.Address) (IL2ForwarderL2ForwarderParams, error) { + return _L1Teleporter.Contract.BuildL2ForwarderParams(&_L1Teleporter.CallOpts, params, caller) +} + +// DetermineTypeAndFees is a free data retrieval call binding the contract method 0xc238b3d1. +// +// Solidity: function determineTypeAndFees((address,address,address,address,address,uint256,(uint256,uint256,uint64,uint64,uint64,uint64,uint256,uint256,uint256,uint256),bytes) params) pure returns(uint256 ethAmount, uint256 feeTokenAmount, uint8 teleportationType, (uint256,uint256,uint256,uint256) costs) +func (_L1Teleporter *L1TeleporterCaller) DetermineTypeAndFees(opts *bind.CallOpts, params IL1TeleporterTeleportParams) (struct { + EthAmount *big.Int + FeeTokenAmount *big.Int + TeleportationType uint8 + Costs IL1TeleporterRetryableGasCosts +}, error) { + var out []interface{} + err := _L1Teleporter.contract.Call(opts, &out, "determineTypeAndFees", params) + + outstruct := new(struct { + EthAmount *big.Int + FeeTokenAmount *big.Int + TeleportationType uint8 + Costs IL1TeleporterRetryableGasCosts + }) + if err != nil { + return *outstruct, err + } + + outstruct.EthAmount = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.FeeTokenAmount = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.TeleportationType = *abi.ConvertType(out[2], new(uint8)).(*uint8) + outstruct.Costs = *abi.ConvertType(out[3], new(IL1TeleporterRetryableGasCosts)).(*IL1TeleporterRetryableGasCosts) + + return *outstruct, err + +} + +// DetermineTypeAndFees is a free data retrieval call binding the contract method 0xc238b3d1. +// +// Solidity: function determineTypeAndFees((address,address,address,address,address,uint256,(uint256,uint256,uint64,uint64,uint64,uint64,uint256,uint256,uint256,uint256),bytes) params) pure returns(uint256 ethAmount, uint256 feeTokenAmount, uint8 teleportationType, (uint256,uint256,uint256,uint256) costs) +func (_L1Teleporter *L1TeleporterSession) DetermineTypeAndFees(params IL1TeleporterTeleportParams) (struct { + EthAmount *big.Int + FeeTokenAmount *big.Int + TeleportationType uint8 + Costs IL1TeleporterRetryableGasCosts +}, error) { + return _L1Teleporter.Contract.DetermineTypeAndFees(&_L1Teleporter.CallOpts, params) +} + +// DetermineTypeAndFees is a free data retrieval call binding the contract method 0xc238b3d1. +// +// Solidity: function determineTypeAndFees((address,address,address,address,address,uint256,(uint256,uint256,uint64,uint64,uint64,uint64,uint256,uint256,uint256,uint256),bytes) params) pure returns(uint256 ethAmount, uint256 feeTokenAmount, uint8 teleportationType, (uint256,uint256,uint256,uint256) costs) +func (_L1Teleporter *L1TeleporterCallerSession) DetermineTypeAndFees(params IL1TeleporterTeleportParams) (struct { + EthAmount *big.Int + FeeTokenAmount *big.Int + TeleportationType uint8 + Costs IL1TeleporterRetryableGasCosts +}, error) { + return _L1Teleporter.Contract.DetermineTypeAndFees(&_L1Teleporter.CallOpts, params) +} + +// GetRoleAdmin is a free data retrieval call binding the contract method 0x248a9ca3. +// +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (_L1Teleporter *L1TeleporterCaller) GetRoleAdmin(opts *bind.CallOpts, role [32]byte) ([32]byte, error) { + var out []interface{} + err := _L1Teleporter.contract.Call(opts, &out, "getRoleAdmin", role) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetRoleAdmin is a free data retrieval call binding the contract method 0x248a9ca3. +// +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (_L1Teleporter *L1TeleporterSession) GetRoleAdmin(role [32]byte) ([32]byte, error) { + return _L1Teleporter.Contract.GetRoleAdmin(&_L1Teleporter.CallOpts, role) +} + +// GetRoleAdmin is a free data retrieval call binding the contract method 0x248a9ca3. +// +// Solidity: function getRoleAdmin(bytes32 role) view returns(bytes32) +func (_L1Teleporter *L1TeleporterCallerSession) GetRoleAdmin(role [32]byte) ([32]byte, error) { + return _L1Teleporter.Contract.GetRoleAdmin(&_L1Teleporter.CallOpts, role) +} + +// HasRole is a free data retrieval call binding the contract method 0x91d14854. +// +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (_L1Teleporter *L1TeleporterCaller) HasRole(opts *bind.CallOpts, role [32]byte, account common.Address) (bool, error) { + var out []interface{} + err := _L1Teleporter.contract.Call(opts, &out, "hasRole", role, account) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// HasRole is a free data retrieval call binding the contract method 0x91d14854. +// +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (_L1Teleporter *L1TeleporterSession) HasRole(role [32]byte, account common.Address) (bool, error) { + return _L1Teleporter.Contract.HasRole(&_L1Teleporter.CallOpts, role, account) +} + +// HasRole is a free data retrieval call binding the contract method 0x91d14854. +// +// Solidity: function hasRole(bytes32 role, address account) view returns(bool) +func (_L1Teleporter *L1TeleporterCallerSession) HasRole(role [32]byte, account common.Address) (bool, error) { + return _L1Teleporter.Contract.HasRole(&_L1Teleporter.CallOpts, role, account) +} + +// L2ForwarderAddress is a free data retrieval call binding the contract method 0xfbabf084. +// +// Solidity: function l2ForwarderAddress(address owner, address routerOrInbox, address to) view returns(address) +func (_L1Teleporter *L1TeleporterCaller) L2ForwarderAddress(opts *bind.CallOpts, owner common.Address, routerOrInbox common.Address, to common.Address) (common.Address, error) { + var out []interface{} + err := _L1Teleporter.contract.Call(opts, &out, "l2ForwarderAddress", owner, routerOrInbox, to) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// L2ForwarderAddress is a free data retrieval call binding the contract method 0xfbabf084. +// +// Solidity: function l2ForwarderAddress(address owner, address routerOrInbox, address to) view returns(address) +func (_L1Teleporter *L1TeleporterSession) L2ForwarderAddress(owner common.Address, routerOrInbox common.Address, to common.Address) (common.Address, error) { + return _L1Teleporter.Contract.L2ForwarderAddress(&_L1Teleporter.CallOpts, owner, routerOrInbox, to) +} + +// L2ForwarderAddress is a free data retrieval call binding the contract method 0xfbabf084. +// +// Solidity: function l2ForwarderAddress(address owner, address routerOrInbox, address to) view returns(address) +func (_L1Teleporter *L1TeleporterCallerSession) L2ForwarderAddress(owner common.Address, routerOrInbox common.Address, to common.Address) (common.Address, error) { + return _L1Teleporter.Contract.L2ForwarderAddress(&_L1Teleporter.CallOpts, owner, routerOrInbox, to) +} + +// L2ForwarderFactory is a free data retrieval call binding the contract method 0x377f017a. +// +// Solidity: function l2ForwarderFactory() view returns(address) +func (_L1Teleporter *L1TeleporterCaller) L2ForwarderFactory(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _L1Teleporter.contract.Call(opts, &out, "l2ForwarderFactory") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// L2ForwarderFactory is a free data retrieval call binding the contract method 0x377f017a. +// +// Solidity: function l2ForwarderFactory() view returns(address) +func (_L1Teleporter *L1TeleporterSession) L2ForwarderFactory() (common.Address, error) { + return _L1Teleporter.Contract.L2ForwarderFactory(&_L1Teleporter.CallOpts) +} + +// L2ForwarderFactory is a free data retrieval call binding the contract method 0x377f017a. +// +// Solidity: function l2ForwarderFactory() view returns(address) +func (_L1Teleporter *L1TeleporterCallerSession) L2ForwarderFactory() (common.Address, error) { + return _L1Teleporter.Contract.L2ForwarderFactory(&_L1Teleporter.CallOpts) +} + +// L2ForwarderImplementation is a free data retrieval call binding the contract method 0xec7d4abd. +// +// Solidity: function l2ForwarderImplementation() view returns(address) +func (_L1Teleporter *L1TeleporterCaller) L2ForwarderImplementation(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _L1Teleporter.contract.Call(opts, &out, "l2ForwarderImplementation") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// L2ForwarderImplementation is a free data retrieval call binding the contract method 0xec7d4abd. +// +// Solidity: function l2ForwarderImplementation() view returns(address) +func (_L1Teleporter *L1TeleporterSession) L2ForwarderImplementation() (common.Address, error) { + return _L1Teleporter.Contract.L2ForwarderImplementation(&_L1Teleporter.CallOpts) +} + +// L2ForwarderImplementation is a free data retrieval call binding the contract method 0xec7d4abd. +// +// Solidity: function l2ForwarderImplementation() view returns(address) +func (_L1Teleporter *L1TeleporterCallerSession) L2ForwarderImplementation() (common.Address, error) { + return _L1Teleporter.Contract.L2ForwarderImplementation(&_L1Teleporter.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L1Teleporter *L1TeleporterCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _L1Teleporter.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L1Teleporter *L1TeleporterSession) Paused() (bool, error) { + return _L1Teleporter.Contract.Paused(&_L1Teleporter.CallOpts) +} + +// Paused is a free data retrieval call binding the contract method 0x5c975abb. +// +// Solidity: function paused() view returns(bool) +func (_L1Teleporter *L1TeleporterCallerSession) Paused() (bool, error) { + return _L1Teleporter.Contract.Paused(&_L1Teleporter.CallOpts) +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_L1Teleporter *L1TeleporterCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) { + var out []interface{} + err := _L1Teleporter.contract.Call(opts, &out, "supportsInterface", interfaceId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_L1Teleporter *L1TeleporterSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _L1Teleporter.Contract.SupportsInterface(&_L1Teleporter.CallOpts, interfaceId) +} + +// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7. +// +// Solidity: function supportsInterface(bytes4 interfaceId) view returns(bool) +func (_L1Teleporter *L1TeleporterCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) { + return _L1Teleporter.Contract.SupportsInterface(&_L1Teleporter.CallOpts, interfaceId) +} + +// GrantRole is a paid mutator transaction binding the contract method 0x2f2ff15d. +// +// Solidity: function grantRole(bytes32 role, address account) returns() +func (_L1Teleporter *L1TeleporterTransactor) GrantRole(opts *bind.TransactOpts, role [32]byte, account common.Address) (*types.Transaction, error) { + return _L1Teleporter.contract.Transact(opts, "grantRole", role, account) +} + +// GrantRole is a paid mutator transaction binding the contract method 0x2f2ff15d. +// +// Solidity: function grantRole(bytes32 role, address account) returns() +func (_L1Teleporter *L1TeleporterSession) GrantRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _L1Teleporter.Contract.GrantRole(&_L1Teleporter.TransactOpts, role, account) +} + +// GrantRole is a paid mutator transaction binding the contract method 0x2f2ff15d. +// +// Solidity: function grantRole(bytes32 role, address account) returns() +func (_L1Teleporter *L1TeleporterTransactorSession) GrantRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _L1Teleporter.Contract.GrantRole(&_L1Teleporter.TransactOpts, role, account) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_L1Teleporter *L1TeleporterTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _L1Teleporter.contract.Transact(opts, "pause") +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_L1Teleporter *L1TeleporterSession) Pause() (*types.Transaction, error) { + return _L1Teleporter.Contract.Pause(&_L1Teleporter.TransactOpts) +} + +// Pause is a paid mutator transaction binding the contract method 0x8456cb59. +// +// Solidity: function pause() returns() +func (_L1Teleporter *L1TeleporterTransactorSession) Pause() (*types.Transaction, error) { + return _L1Teleporter.Contract.Pause(&_L1Teleporter.TransactOpts) +} + +// RenounceRole is a paid mutator transaction binding the contract method 0x36568abe. +// +// Solidity: function renounceRole(bytes32 role, address account) returns() +func (_L1Teleporter *L1TeleporterTransactor) RenounceRole(opts *bind.TransactOpts, role [32]byte, account common.Address) (*types.Transaction, error) { + return _L1Teleporter.contract.Transact(opts, "renounceRole", role, account) +} + +// RenounceRole is a paid mutator transaction binding the contract method 0x36568abe. +// +// Solidity: function renounceRole(bytes32 role, address account) returns() +func (_L1Teleporter *L1TeleporterSession) RenounceRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _L1Teleporter.Contract.RenounceRole(&_L1Teleporter.TransactOpts, role, account) +} + +// RenounceRole is a paid mutator transaction binding the contract method 0x36568abe. +// +// Solidity: function renounceRole(bytes32 role, address account) returns() +func (_L1Teleporter *L1TeleporterTransactorSession) RenounceRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _L1Teleporter.Contract.RenounceRole(&_L1Teleporter.TransactOpts, role, account) +} + +// RevokeRole is a paid mutator transaction binding the contract method 0xd547741f. +// +// Solidity: function revokeRole(bytes32 role, address account) returns() +func (_L1Teleporter *L1TeleporterTransactor) RevokeRole(opts *bind.TransactOpts, role [32]byte, account common.Address) (*types.Transaction, error) { + return _L1Teleporter.contract.Transact(opts, "revokeRole", role, account) +} + +// RevokeRole is a paid mutator transaction binding the contract method 0xd547741f. +// +// Solidity: function revokeRole(bytes32 role, address account) returns() +func (_L1Teleporter *L1TeleporterSession) RevokeRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _L1Teleporter.Contract.RevokeRole(&_L1Teleporter.TransactOpts, role, account) +} + +// RevokeRole is a paid mutator transaction binding the contract method 0xd547741f. +// +// Solidity: function revokeRole(bytes32 role, address account) returns() +func (_L1Teleporter *L1TeleporterTransactorSession) RevokeRole(role [32]byte, account common.Address) (*types.Transaction, error) { + return _L1Teleporter.Contract.RevokeRole(&_L1Teleporter.TransactOpts, role, account) +} + +// Teleport is a paid mutator transaction binding the contract method 0x2478a34b. +// +// Solidity: function teleport((address,address,address,address,address,uint256,(uint256,uint256,uint64,uint64,uint64,uint64,uint256,uint256,uint256,uint256),bytes) params) payable returns() +func (_L1Teleporter *L1TeleporterTransactor) Teleport(opts *bind.TransactOpts, params IL1TeleporterTeleportParams) (*types.Transaction, error) { + return _L1Teleporter.contract.Transact(opts, "teleport", params) +} + +// Teleport is a paid mutator transaction binding the contract method 0x2478a34b. +// +// Solidity: function teleport((address,address,address,address,address,uint256,(uint256,uint256,uint64,uint64,uint64,uint64,uint256,uint256,uint256,uint256),bytes) params) payable returns() +func (_L1Teleporter *L1TeleporterSession) Teleport(params IL1TeleporterTeleportParams) (*types.Transaction, error) { + return _L1Teleporter.Contract.Teleport(&_L1Teleporter.TransactOpts, params) +} + +// Teleport is a paid mutator transaction binding the contract method 0x2478a34b. +// +// Solidity: function teleport((address,address,address,address,address,uint256,(uint256,uint256,uint64,uint64,uint64,uint64,uint256,uint256,uint256,uint256),bytes) params) payable returns() +func (_L1Teleporter *L1TeleporterTransactorSession) Teleport(params IL1TeleporterTeleportParams) (*types.Transaction, error) { + return _L1Teleporter.Contract.Teleport(&_L1Teleporter.TransactOpts, params) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_L1Teleporter *L1TeleporterTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _L1Teleporter.contract.Transact(opts, "unpause") +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_L1Teleporter *L1TeleporterSession) Unpause() (*types.Transaction, error) { + return _L1Teleporter.Contract.Unpause(&_L1Teleporter.TransactOpts) +} + +// Unpause is a paid mutator transaction binding the contract method 0x3f4ba83a. +// +// Solidity: function unpause() returns() +func (_L1Teleporter *L1TeleporterTransactorSession) Unpause() (*types.Transaction, error) { + return _L1Teleporter.Contract.Unpause(&_L1Teleporter.TransactOpts) +} + +// L1TeleporterPausedIterator is returned from FilterPaused and is used to iterate over the raw logs and unpacked data for Paused events raised by the L1Teleporter contract. +type L1TeleporterPausedIterator struct { + Event *L1TeleporterPaused // 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 *L1TeleporterPausedIterator) 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(L1TeleporterPaused) + 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(L1TeleporterPaused) + 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 *L1TeleporterPausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *L1TeleporterPausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// L1TeleporterPaused represents a Paused event raised by the L1Teleporter contract. +type L1TeleporterPaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPaused is a free log retrieval operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_L1Teleporter *L1TeleporterFilterer) FilterPaused(opts *bind.FilterOpts) (*L1TeleporterPausedIterator, error) { + + logs, sub, err := _L1Teleporter.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &L1TeleporterPausedIterator{contract: _L1Teleporter.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +// WatchPaused is a free log subscription operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_L1Teleporter *L1TeleporterFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *L1TeleporterPaused) (event.Subscription, error) { + + logs, sub, err := _L1Teleporter.contract.WatchLogs(opts, "Paused") + 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(L1TeleporterPaused) + if err := _L1Teleporter.contract.UnpackLog(event, "Paused", 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 +} + +// ParsePaused is a log parse operation binding the contract event 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258. +// +// Solidity: event Paused(address account) +func (_L1Teleporter *L1TeleporterFilterer) ParsePaused(log types.Log) (*L1TeleporterPaused, error) { + event := new(L1TeleporterPaused) + if err := _L1Teleporter.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// L1TeleporterRoleAdminChangedIterator is returned from FilterRoleAdminChanged and is used to iterate over the raw logs and unpacked data for RoleAdminChanged events raised by the L1Teleporter contract. +type L1TeleporterRoleAdminChangedIterator struct { + Event *L1TeleporterRoleAdminChanged // 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 *L1TeleporterRoleAdminChangedIterator) 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(L1TeleporterRoleAdminChanged) + 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(L1TeleporterRoleAdminChanged) + 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 *L1TeleporterRoleAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *L1TeleporterRoleAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// L1TeleporterRoleAdminChanged represents a RoleAdminChanged event raised by the L1Teleporter contract. +type L1TeleporterRoleAdminChanged struct { + Role [32]byte + PreviousAdminRole [32]byte + NewAdminRole [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRoleAdminChanged is a free log retrieval operation binding the contract event 0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff. +// +// Solidity: event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole) +func (_L1Teleporter *L1TeleporterFilterer) FilterRoleAdminChanged(opts *bind.FilterOpts, role [][32]byte, previousAdminRole [][32]byte, newAdminRole [][32]byte) (*L1TeleporterRoleAdminChangedIterator, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var previousAdminRoleRule []interface{} + for _, previousAdminRoleItem := range previousAdminRole { + previousAdminRoleRule = append(previousAdminRoleRule, previousAdminRoleItem) + } + var newAdminRoleRule []interface{} + for _, newAdminRoleItem := range newAdminRole { + newAdminRoleRule = append(newAdminRoleRule, newAdminRoleItem) + } + + logs, sub, err := _L1Teleporter.contract.FilterLogs(opts, "RoleAdminChanged", roleRule, previousAdminRoleRule, newAdminRoleRule) + if err != nil { + return nil, err + } + return &L1TeleporterRoleAdminChangedIterator{contract: _L1Teleporter.contract, event: "RoleAdminChanged", logs: logs, sub: sub}, nil +} + +// WatchRoleAdminChanged is a free log subscription operation binding the contract event 0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff. +// +// Solidity: event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole) +func (_L1Teleporter *L1TeleporterFilterer) WatchRoleAdminChanged(opts *bind.WatchOpts, sink chan<- *L1TeleporterRoleAdminChanged, role [][32]byte, previousAdminRole [][32]byte, newAdminRole [][32]byte) (event.Subscription, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var previousAdminRoleRule []interface{} + for _, previousAdminRoleItem := range previousAdminRole { + previousAdminRoleRule = append(previousAdminRoleRule, previousAdminRoleItem) + } + var newAdminRoleRule []interface{} + for _, newAdminRoleItem := range newAdminRole { + newAdminRoleRule = append(newAdminRoleRule, newAdminRoleItem) + } + + logs, sub, err := _L1Teleporter.contract.WatchLogs(opts, "RoleAdminChanged", roleRule, previousAdminRoleRule, newAdminRoleRule) + 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(L1TeleporterRoleAdminChanged) + if err := _L1Teleporter.contract.UnpackLog(event, "RoleAdminChanged", 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 +} + +// ParseRoleAdminChanged is a log parse operation binding the contract event 0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff. +// +// Solidity: event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole) +func (_L1Teleporter *L1TeleporterFilterer) ParseRoleAdminChanged(log types.Log) (*L1TeleporterRoleAdminChanged, error) { + event := new(L1TeleporterRoleAdminChanged) + if err := _L1Teleporter.contract.UnpackLog(event, "RoleAdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// L1TeleporterRoleGrantedIterator is returned from FilterRoleGranted and is used to iterate over the raw logs and unpacked data for RoleGranted events raised by the L1Teleporter contract. +type L1TeleporterRoleGrantedIterator struct { + Event *L1TeleporterRoleGranted // 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 *L1TeleporterRoleGrantedIterator) 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(L1TeleporterRoleGranted) + 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(L1TeleporterRoleGranted) + 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 *L1TeleporterRoleGrantedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *L1TeleporterRoleGrantedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// L1TeleporterRoleGranted represents a RoleGranted event raised by the L1Teleporter contract. +type L1TeleporterRoleGranted struct { + Role [32]byte + Account common.Address + Sender common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRoleGranted is a free log retrieval operation binding the contract event 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d. +// +// Solidity: event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender) +func (_L1Teleporter *L1TeleporterFilterer) FilterRoleGranted(opts *bind.FilterOpts, role [][32]byte, account []common.Address, sender []common.Address) (*L1TeleporterRoleGrantedIterator, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _L1Teleporter.contract.FilterLogs(opts, "RoleGranted", roleRule, accountRule, senderRule) + if err != nil { + return nil, err + } + return &L1TeleporterRoleGrantedIterator{contract: _L1Teleporter.contract, event: "RoleGranted", logs: logs, sub: sub}, nil +} + +// WatchRoleGranted is a free log subscription operation binding the contract event 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d. +// +// Solidity: event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender) +func (_L1Teleporter *L1TeleporterFilterer) WatchRoleGranted(opts *bind.WatchOpts, sink chan<- *L1TeleporterRoleGranted, role [][32]byte, account []common.Address, sender []common.Address) (event.Subscription, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _L1Teleporter.contract.WatchLogs(opts, "RoleGranted", roleRule, accountRule, senderRule) + 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(L1TeleporterRoleGranted) + if err := _L1Teleporter.contract.UnpackLog(event, "RoleGranted", 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 +} + +// ParseRoleGranted is a log parse operation binding the contract event 0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d. +// +// Solidity: event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender) +func (_L1Teleporter *L1TeleporterFilterer) ParseRoleGranted(log types.Log) (*L1TeleporterRoleGranted, error) { + event := new(L1TeleporterRoleGranted) + if err := _L1Teleporter.contract.UnpackLog(event, "RoleGranted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// L1TeleporterRoleRevokedIterator is returned from FilterRoleRevoked and is used to iterate over the raw logs and unpacked data for RoleRevoked events raised by the L1Teleporter contract. +type L1TeleporterRoleRevokedIterator struct { + Event *L1TeleporterRoleRevoked // 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 *L1TeleporterRoleRevokedIterator) 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(L1TeleporterRoleRevoked) + 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(L1TeleporterRoleRevoked) + 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 *L1TeleporterRoleRevokedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *L1TeleporterRoleRevokedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// L1TeleporterRoleRevoked represents a RoleRevoked event raised by the L1Teleporter contract. +type L1TeleporterRoleRevoked struct { + Role [32]byte + Account common.Address + Sender common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRoleRevoked is a free log retrieval operation binding the contract event 0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b. +// +// Solidity: event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender) +func (_L1Teleporter *L1TeleporterFilterer) FilterRoleRevoked(opts *bind.FilterOpts, role [][32]byte, account []common.Address, sender []common.Address) (*L1TeleporterRoleRevokedIterator, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _L1Teleporter.contract.FilterLogs(opts, "RoleRevoked", roleRule, accountRule, senderRule) + if err != nil { + return nil, err + } + return &L1TeleporterRoleRevokedIterator{contract: _L1Teleporter.contract, event: "RoleRevoked", logs: logs, sub: sub}, nil +} + +// WatchRoleRevoked is a free log subscription operation binding the contract event 0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b. +// +// Solidity: event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender) +func (_L1Teleporter *L1TeleporterFilterer) WatchRoleRevoked(opts *bind.WatchOpts, sink chan<- *L1TeleporterRoleRevoked, role [][32]byte, account []common.Address, sender []common.Address) (event.Subscription, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _L1Teleporter.contract.WatchLogs(opts, "RoleRevoked", roleRule, accountRule, senderRule) + 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(L1TeleporterRoleRevoked) + if err := _L1Teleporter.contract.UnpackLog(event, "RoleRevoked", 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 +} + +// ParseRoleRevoked is a log parse operation binding the contract event 0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b. +// +// Solidity: event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender) +func (_L1Teleporter *L1TeleporterFilterer) ParseRoleRevoked(log types.Log) (*L1TeleporterRoleRevoked, error) { + event := new(L1TeleporterRoleRevoked) + if err := _L1Teleporter.contract.UnpackLog(event, "RoleRevoked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// L1TeleporterTeleportedIterator is returned from FilterTeleported and is used to iterate over the raw logs and unpacked data for Teleported events raised by the L1Teleporter contract. +type L1TeleporterTeleportedIterator struct { + Event *L1TeleporterTeleported // 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 *L1TeleporterTeleportedIterator) 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(L1TeleporterTeleported) + 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(L1TeleporterTeleported) + 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 *L1TeleporterTeleportedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *L1TeleporterTeleportedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// L1TeleporterTeleported represents a Teleported event raised by the L1Teleporter contract. +type L1TeleporterTeleported struct { + Sender common.Address + L1Token common.Address + L3FeeTokenL1Addr common.Address + L1l2Router common.Address + L2l3RouterOrInbox common.Address + To common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTeleported is a free log retrieval operation binding the contract event 0x762fcae5372ec0a8b89250dca23af574afcad1e9db4425b0a2d9e8f9e8a64ad0. +// +// Solidity: event Teleported(address indexed sender, address l1Token, address l3FeeTokenL1Addr, address l1l2Router, address l2l3RouterOrInbox, address to, uint256 amount) +func (_L1Teleporter *L1TeleporterFilterer) FilterTeleported(opts *bind.FilterOpts, sender []common.Address) (*L1TeleporterTeleportedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _L1Teleporter.contract.FilterLogs(opts, "Teleported", senderRule) + if err != nil { + return nil, err + } + return &L1TeleporterTeleportedIterator{contract: _L1Teleporter.contract, event: "Teleported", logs: logs, sub: sub}, nil +} + +// WatchTeleported is a free log subscription operation binding the contract event 0x762fcae5372ec0a8b89250dca23af574afcad1e9db4425b0a2d9e8f9e8a64ad0. +// +// Solidity: event Teleported(address indexed sender, address l1Token, address l3FeeTokenL1Addr, address l1l2Router, address l2l3RouterOrInbox, address to, uint256 amount) +func (_L1Teleporter *L1TeleporterFilterer) WatchTeleported(opts *bind.WatchOpts, sink chan<- *L1TeleporterTeleported, sender []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _L1Teleporter.contract.WatchLogs(opts, "Teleported", senderRule) + 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(L1TeleporterTeleported) + if err := _L1Teleporter.contract.UnpackLog(event, "Teleported", 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 +} + +// ParseTeleported is a log parse operation binding the contract event 0x762fcae5372ec0a8b89250dca23af574afcad1e9db4425b0a2d9e8f9e8a64ad0. +// +// Solidity: event Teleported(address indexed sender, address l1Token, address l3FeeTokenL1Addr, address l1l2Router, address l2l3RouterOrInbox, address to, uint256 amount) +func (_L1Teleporter *L1TeleporterFilterer) ParseTeleported(log types.Log) (*L1TeleporterTeleported, error) { + event := new(L1TeleporterTeleported) + if err := _L1Teleporter.contract.UnpackLog(event, "Teleported", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// L1TeleporterUnpausedIterator is returned from FilterUnpaused and is used to iterate over the raw logs and unpacked data for Unpaused events raised by the L1Teleporter contract. +type L1TeleporterUnpausedIterator struct { + Event *L1TeleporterUnpaused // 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 *L1TeleporterUnpausedIterator) 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(L1TeleporterUnpaused) + 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(L1TeleporterUnpaused) + 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 *L1TeleporterUnpausedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *L1TeleporterUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// L1TeleporterUnpaused represents a Unpaused event raised by the L1Teleporter contract. +type L1TeleporterUnpaused struct { + Account common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnpaused is a free log retrieval operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_L1Teleporter *L1TeleporterFilterer) FilterUnpaused(opts *bind.FilterOpts) (*L1TeleporterUnpausedIterator, error) { + + logs, sub, err := _L1Teleporter.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &L1TeleporterUnpausedIterator{contract: _L1Teleporter.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +// WatchUnpaused is a free log subscription operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_L1Teleporter *L1TeleporterFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *L1TeleporterUnpaused) (event.Subscription, error) { + + logs, sub, err := _L1Teleporter.contract.WatchLogs(opts, "Unpaused") + 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(L1TeleporterUnpaused) + if err := _L1Teleporter.contract.UnpackLog(event, "Unpaused", 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 +} + +// ParseUnpaused is a log parse operation binding the contract event 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa. +// +// Solidity: event Unpaused(address account) +func (_L1Teleporter *L1TeleporterFilterer) ParseUnpaused(log types.Log) (*L1TeleporterUnpaused, error) { + event := new(L1TeleporterUnpaused) + if err := _L1Teleporter.contract.UnpackLog(event, "Unpaused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func CreateL1TeleporterDeploymentCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc string + var gasLimit uint64 + var simulate bool + var timeout uint + + var l2ForwarderFactory common.Address + var l2ForwarderFactoryRaw string + var l2ForwarderImplementation common.Address + var l2ForwarderImplementationRaw string + var admin common.Address + var adminRaw string + var pauser common.Address + var pauserRaw string + + cmd := &cobra.Command{ + Use: "deploy", + Short: "Deploy a new L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if l2ForwarderFactoryRaw == "" { + return fmt.Errorf("--l-2-forwarder-factory argument not specified") + } else if !common.IsHexAddress(l2ForwarderFactoryRaw) { + return fmt.Errorf("--l-2-forwarder-factory argument is not a valid Ethereum address") + } + l2ForwarderFactory = common.HexToAddress(l2ForwarderFactoryRaw) + + if l2ForwarderImplementationRaw == "" { + return fmt.Errorf("--l-2-forwarder-implementation argument not specified") + } else if !common.IsHexAddress(l2ForwarderImplementationRaw) { + return fmt.Errorf("--l-2-forwarder-implementation argument is not a valid Ethereum address") + } + l2ForwarderImplementation = common.HexToAddress(l2ForwarderImplementationRaw) + + if adminRaw == "" { + return fmt.Errorf("--admin argument not specified") + } else if !common.IsHexAddress(adminRaw) { + return fmt.Errorf("--admin argument is not a valid Ethereum address") + } + admin = common.HexToAddress(adminRaw) + + if pauserRaw == "" { + return fmt.Errorf("--pauser argument not specified") + } else if !common.IsHexAddress(pauserRaw) { + return fmt.Errorf("--pauser argument is not a valid Ethereum address") + } + pauser = common.HexToAddress(pauserRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + address, deploymentTransaction, _, deploymentErr := DeployL1Teleporter( + transactionOpts, + client, + l2ForwarderFactory, + l2ForwarderImplementation, + admin, + pauser, + ) + if deploymentErr != nil { + return deploymentErr + } + + cmd.Printf("Transaction hash: %s\nContract address: %s\n", deploymentTransaction.Hash().Hex(), address.Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + Data: deploymentTransaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := deploymentTransaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + + cmd.Flags().StringVar(&l2ForwarderFactoryRaw, "l-2-forwarder-factory", "", "l-2-forwarder-factory argument") + cmd.Flags().StringVar(&l2ForwarderImplementationRaw, "l-2-forwarder-implementation", "", "l-2-forwarder-implementation argument") + cmd.Flags().StringVar(&adminRaw, "admin", "", "admin argument") + cmd.Flags().StringVar(&pauserRaw, "pauser", "", "pauser argument") + + return cmd +} + +func CreateSkipfeetokenmagicaddressCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "skipfeetokenmagicaddress", + Short: "Call the SKIPFEETOKENMAGICADDRESS view method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L1TeleporterCallerSession{ + Contract: &contract.L1TeleporterCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.SKIPFEETOKENMAGICADDRESS() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateHasRoleCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var role [32]byte + var roleRaw string + var account common.Address + var accountRaw string + + var capture0 bool + + cmd := &cobra.Command{ + Use: "has-role", + Short: "Call the HasRole view method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var hexDecoderoleErr error + + var intermediateroleLeaf []byte + intermediateroleLeaf, hexDecoderoleErr = hex.DecodeString(roleRaw) + if hexDecoderoleErr != nil { + return hexDecoderoleErr + } + role = [32]byte(intermediateroleLeaf[:32]) + + if accountRaw == "" { + return fmt.Errorf("--account argument not specified") + } else if !common.IsHexAddress(accountRaw) { + return fmt.Errorf("--account argument is not a valid Ethereum address") + } + account = common.HexToAddress(accountRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L1TeleporterCallerSession{ + Contract: &contract.L1TeleporterCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.HasRole( + role, + account, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %t\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&roleRaw, "role", "", "role argument") + cmd.Flags().StringVar(&accountRaw, "account", "", "account argument") + + return cmd +} +func CreateL2ForwarderImplementationCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "l-2-forwarder-implementation", + Short: "Call the L2ForwarderImplementation view method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L1TeleporterCallerSession{ + Contract: &contract.L1TeleporterCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.L2ForwarderImplementation() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateL2ForwarderAddressCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var owner common.Address + var ownerRaw string + var routerOrInbox common.Address + var routerOrInboxRaw string + var to0 common.Address + var to0Raw string + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "l-2-forwarder-address", + Short: "Call the L2ForwarderAddress view method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if ownerRaw == "" { + return fmt.Errorf("--owner argument not specified") + } else if !common.IsHexAddress(ownerRaw) { + return fmt.Errorf("--owner argument is not a valid Ethereum address") + } + owner = common.HexToAddress(ownerRaw) + + if routerOrInboxRaw == "" { + return fmt.Errorf("--router-or-inbox argument not specified") + } else if !common.IsHexAddress(routerOrInboxRaw) { + return fmt.Errorf("--router-or-inbox argument is not a valid Ethereum address") + } + routerOrInbox = common.HexToAddress(routerOrInboxRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L1TeleporterCallerSession{ + Contract: &contract.L1TeleporterCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.L2ForwarderAddress( + owner, + routerOrInbox, + to0, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&ownerRaw, "owner", "", "owner argument") + cmd.Flags().StringVar(&routerOrInboxRaw, "router-or-inbox", "", "router-or-inbox argument") + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument") + + return cmd +} +func CreateL2ForwarderFactoryCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "l-2-forwarder-factory", + Short: "Call the L2ForwarderFactory view method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L1TeleporterCallerSession{ + Contract: &contract.L1TeleporterCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.L2ForwarderFactory() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreatePausedCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 bool + + cmd := &cobra.Command{ + Use: "paused", + Short: "Call the Paused view method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L1TeleporterCallerSession{ + Contract: &contract.L1TeleporterCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.Paused() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %t\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateDefaultadminroleCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 [32]byte + + cmd := &cobra.Command{ + Use: "defaultadminrole", + Short: "Call the DEFAULTADMINROLE view method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L1TeleporterCallerSession{ + Contract: &contract.L1TeleporterCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.DEFAULTADMINROLE() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreatePauserroleCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 [32]byte + + cmd := &cobra.Command{ + Use: "pauserrole", + Short: "Call the PAUSERROLE view method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L1TeleporterCallerSession{ + Contract: &contract.L1TeleporterCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.PAUSERROLE() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateBuildL2ForwarderParamsCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var params IL1TeleporterTeleportParams + var paramsRaw string + var caller common.Address + var callerRaw string + + var capture0 IL2ForwarderL2ForwarderParams + + cmd := &cobra.Command{ + Use: "build-l-2-forwarder-params", + Short: "Call the BuildL2ForwarderParams view method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if paramsRaw == "" { + return fmt.Errorf("--params argument not specified") + } else if strings.HasPrefix(paramsRaw, "@") { + filename := strings.TrimPrefix(paramsRaw, "@") + contents, readErr := os.ReadFile(filename) + if readErr != nil { + return readErr + } + unmarshalErr := json.Unmarshal(contents, ¶ms) + if unmarshalErr != nil { + return unmarshalErr + } + } else { + unmarshalErr := json.Unmarshal([]byte(paramsRaw), ¶ms) + if unmarshalErr != nil { + return unmarshalErr + } + } + + if callerRaw == "" { + return fmt.Errorf("--caller argument not specified") + } else if !common.IsHexAddress(callerRaw) { + return fmt.Errorf("--caller argument is not a valid Ethereum address") + } + caller = common.HexToAddress(callerRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L1TeleporterCallerSession{ + Contract: &contract.L1TeleporterCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.BuildL2ForwarderParams( + params, + caller, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(¶msRaw, "params", "", "params argument") + cmd.Flags().StringVar(&callerRaw, "caller", "", "caller argument") + + return cmd +} +func CreateDetermineTypeAndFeesCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var params IL1TeleporterTeleportParams + var paramsRaw string + + var capture0 struct { + EthAmount *big.Int + FeeTokenAmount *big.Int + TeleportationType uint8 + Costs IL1TeleporterRetryableGasCosts + } + + cmd := &cobra.Command{ + Use: "determine-type-and-fees", + Short: "Call the DetermineTypeAndFees view method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if paramsRaw == "" { + return fmt.Errorf("--params argument not specified") + } else if strings.HasPrefix(paramsRaw, "@") { + filename := strings.TrimPrefix(paramsRaw, "@") + contents, readErr := os.ReadFile(filename) + if readErr != nil { + return readErr + } + unmarshalErr := json.Unmarshal(contents, ¶ms) + if unmarshalErr != nil { + return unmarshalErr + } + } else { + unmarshalErr := json.Unmarshal([]byte(paramsRaw), ¶ms) + if unmarshalErr != nil { + return unmarshalErr + } + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L1TeleporterCallerSession{ + Contract: &contract.L1TeleporterCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.DetermineTypeAndFees( + params, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(¶msRaw, "params", "", "params argument") + + return cmd +} +func CreateGetRoleAdminCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var role [32]byte + var roleRaw string + + var capture0 [32]byte + + cmd := &cobra.Command{ + Use: "get-role-admin", + Short: "Call the GetRoleAdmin view method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var hexDecoderoleErr error + + var intermediateroleLeaf []byte + intermediateroleLeaf, hexDecoderoleErr = hex.DecodeString(roleRaw) + if hexDecoderoleErr != nil { + return hexDecoderoleErr + } + role = [32]byte(intermediateroleLeaf[:32]) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L1TeleporterCallerSession{ + Contract: &contract.L1TeleporterCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.GetRoleAdmin( + role, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&roleRaw, "role", "", "role argument") + + return cmd +} +func CreateSupportsInterfaceCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var interfaceId [4]byte + var interfaceIdRaw string + + var capture0 bool + + cmd := &cobra.Command{ + Use: "supports-interface", + Short: "Call the SupportsInterface view method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var hexDecodeinterfaceIdErr error + + var intermediateinterfaceIdLeaf []byte + intermediateinterfaceIdLeaf, hexDecodeinterfaceIdErr = hex.DecodeString(interfaceIdRaw) + if hexDecodeinterfaceIdErr != nil { + return hexDecodeinterfaceIdErr + } + interfaceId = [4]byte(intermediateinterfaceIdLeaf[:4]) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L1TeleporterCallerSession{ + Contract: &contract.L1TeleporterCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.SupportsInterface( + interfaceId, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %t\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&interfaceIdRaw, "interface-id", "", "interface-id argument") + + return cmd +} + +func CreateUnpauseCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + cmd := &cobra.Command{ + Use: "unpause", + Short: "Execute the Unpause method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := L1TeleporterTransactorSession{ + Contract: &contract.L1TeleporterTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.Unpause() + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + return cmd +} +func CreateGrantRoleCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var role [32]byte + var roleRaw string + var account common.Address + var accountRaw string + + cmd := &cobra.Command{ + Use: "grant-role", + Short: "Execute the GrantRole method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var hexDecoderoleErr error + + var intermediateroleLeaf []byte + intermediateroleLeaf, hexDecoderoleErr = hex.DecodeString(roleRaw) + if hexDecoderoleErr != nil { + return hexDecoderoleErr + } + role = [32]byte(intermediateroleLeaf[:32]) + + if accountRaw == "" { + return fmt.Errorf("--account argument not specified") + } else if !common.IsHexAddress(accountRaw) { + return fmt.Errorf("--account argument is not a valid Ethereum address") + } + account = common.HexToAddress(accountRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := L1TeleporterTransactorSession{ + Contract: &contract.L1TeleporterTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.GrantRole( + role, + account, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&roleRaw, "role", "", "role argument") + cmd.Flags().StringVar(&accountRaw, "account", "", "account argument") + + return cmd +} +func CreatePauseCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + cmd := &cobra.Command{ + Use: "pause", + Short: "Execute the Pause method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := L1TeleporterTransactorSession{ + Contract: &contract.L1TeleporterTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.Pause() + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + return cmd +} +func CreateRenounceRoleCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var role [32]byte + var roleRaw string + var account common.Address + var accountRaw string + + cmd := &cobra.Command{ + Use: "renounce-role", + Short: "Execute the RenounceRole method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var hexDecoderoleErr error + + var intermediateroleLeaf []byte + intermediateroleLeaf, hexDecoderoleErr = hex.DecodeString(roleRaw) + if hexDecoderoleErr != nil { + return hexDecoderoleErr + } + role = [32]byte(intermediateroleLeaf[:32]) + + if accountRaw == "" { + return fmt.Errorf("--account argument not specified") + } else if !common.IsHexAddress(accountRaw) { + return fmt.Errorf("--account argument is not a valid Ethereum address") + } + account = common.HexToAddress(accountRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := L1TeleporterTransactorSession{ + Contract: &contract.L1TeleporterTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.RenounceRole( + role, + account, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&roleRaw, "role", "", "role argument") + cmd.Flags().StringVar(&accountRaw, "account", "", "account argument") + + return cmd +} +func CreateRevokeRoleCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var role [32]byte + var roleRaw string + var account common.Address + var accountRaw string + + cmd := &cobra.Command{ + Use: "revoke-role", + Short: "Execute the RevokeRole method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + var hexDecoderoleErr error + + var intermediateroleLeaf []byte + intermediateroleLeaf, hexDecoderoleErr = hex.DecodeString(roleRaw) + if hexDecoderoleErr != nil { + return hexDecoderoleErr + } + role = [32]byte(intermediateroleLeaf[:32]) + + if accountRaw == "" { + return fmt.Errorf("--account argument not specified") + } else if !common.IsHexAddress(accountRaw) { + return fmt.Errorf("--account argument is not a valid Ethereum address") + } + account = common.HexToAddress(accountRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := L1TeleporterTransactorSession{ + Contract: &contract.L1TeleporterTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.RevokeRole( + role, + account, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&roleRaw, "role", "", "role argument") + cmd.Flags().StringVar(&accountRaw, "account", "", "account argument") + + return cmd +} +func CreateTeleportCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var params IL1TeleporterTeleportParams + var paramsRaw string + + cmd := &cobra.Command{ + Use: "teleport", + Short: "Execute the Teleport method on a L1Teleporter contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if paramsRaw == "" { + return fmt.Errorf("--params argument not specified") + } else if strings.HasPrefix(paramsRaw, "@") { + filename := strings.TrimPrefix(paramsRaw, "@") + contents, readErr := os.ReadFile(filename) + if readErr != nil { + return readErr + } + unmarshalErr := json.Unmarshal(contents, ¶ms) + if unmarshalErr != nil { + return unmarshalErr + } + } else { + unmarshalErr := json.Unmarshal([]byte(paramsRaw), ¶ms) + if unmarshalErr != nil { + return unmarshalErr + } + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewL1Teleporter(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := L1TeleporterTransactorSession{ + Contract: &contract.L1TeleporterTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.Teleport( + params, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(¶msRaw, "params", "", "params argument") + + return cmd +} + +var ErrNoRPCURL error = errors.New("no RPC URL provided -- please pass an RPC URL from the command line or set the L_1_TELEPORTER_RPC_URL environment variable") + +// Generates an Ethereum client to the JSONRPC API at the given URL. If rpcURL is empty, then it +// attempts to read the RPC URL from the L_1_TELEPORTER_RPC_URL environment variable. If that is empty, +// too, then it returns an error. +func NewClient(rpcURL string) (*ethclient.Client, error) { + if rpcURL == "" { + rpcURL = os.Getenv("L_1_TELEPORTER_RPC_URL") + } + + if rpcURL == "" { + return nil, ErrNoRPCURL + } + + client, err := ethclient.Dial(rpcURL) + return client, err +} + +// Creates a new context to be used when interacting with the chain client. +func NewChainContext(timeout uint) (context.Context, context.CancelFunc) { + baseCtx := context.Background() + parsedTimeout := time.Duration(timeout) * time.Second + ctx, cancel := context.WithTimeout(baseCtx, parsedTimeout) + return ctx, cancel +} + +// Unlocks a key from a keystore (byte contents of a keystore file) with the given password. +func UnlockKeystore(keystoreData []byte, password string) (*keystore.Key, error) { + key, err := keystore.DecryptKey(keystoreData, password) + return key, err +} + +// Loads a key from file, prompting the user for the password if it is not provided as a function argument. +func KeyFromFile(keystoreFile string, password string) (*keystore.Key, error) { + var emptyKey *keystore.Key + keystoreContent, readErr := os.ReadFile(keystoreFile) + if readErr != nil { + return emptyKey, readErr + } + + // If password is "", prompt user for password. + if password == "" { + fmt.Printf("Please provide a password for keystore (%s): ", keystoreFile) + passwordRaw, inputErr := term.ReadPassword(int(os.Stdin.Fd())) + if inputErr != nil { + return emptyKey, fmt.Errorf("error reading password: %s", inputErr.Error()) + } + fmt.Print("\n") + password = string(passwordRaw) + } + + key, err := UnlockKeystore(keystoreContent, password) + return key, err +} + +// This method is used to set the parameters on a view call from command line arguments (represented mostly as +// strings). +func SetCallParametersFromArgs(opts *bind.CallOpts, pending bool, fromAddress, blockNumber string) { + if pending { + opts.Pending = true + } + + if fromAddress != "" { + opts.From = common.HexToAddress(fromAddress) + } + + if blockNumber != "" { + opts.BlockNumber = new(big.Int) + opts.BlockNumber.SetString(blockNumber, 0) + } +} + +// This method is used to set the parameters on a transaction from command line arguments (represented mostly as +// strings). +func SetTransactionParametersFromArgs(opts *bind.TransactOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas string, gasLimit uint64, noSend bool) { + if nonce != "" { + opts.Nonce = new(big.Int) + opts.Nonce.SetString(nonce, 0) + } + + if value != "" { + opts.Value = new(big.Int) + opts.Value.SetString(value, 0) + } + + if gasPrice != "" { + opts.GasPrice = new(big.Int) + opts.GasPrice.SetString(gasPrice, 0) + } + + if maxFeePerGas != "" { + opts.GasFeeCap = new(big.Int) + opts.GasFeeCap.SetString(maxFeePerGas, 0) + } + + if maxPriorityFeePerGas != "" { + opts.GasTipCap = new(big.Int) + opts.GasTipCap.SetString(maxPriorityFeePerGas, 0) + } + + if gasLimit != 0 { + opts.GasLimit = gasLimit + } + + opts.NoSend = noSend +} + +func CreateL1TeleporterCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "l-1-teleporter", + Short: "Interact with the L1Teleporter contract", + Run: func(cmd *cobra.Command, args []string) { + cmd.Help() + }, + } + + cmd.SetOut(os.Stdout) + + DeployGroup := &cobra.Group{ + ID: "deploy", Title: "Commands which deploy contracts", + } + cmd.AddGroup(DeployGroup) + ViewGroup := &cobra.Group{ + ID: "view", Title: "Commands which view contract state", + } + TransactGroup := &cobra.Group{ + ID: "transact", Title: "Commands which submit transactions", + } + cmd.AddGroup(ViewGroup, TransactGroup) + + cmdDeployL1Teleporter := CreateL1TeleporterDeploymentCommand() + cmdDeployL1Teleporter.GroupID = DeployGroup.ID + cmd.AddCommand(cmdDeployL1Teleporter) + + cmdViewSKIPFEETOKENMAGICADDRESS := CreateSkipfeetokenmagicaddressCommand() + cmdViewSKIPFEETOKENMAGICADDRESS.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewSKIPFEETOKENMAGICADDRESS) + cmdViewHasRole := CreateHasRoleCommand() + cmdViewHasRole.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewHasRole) + cmdViewL2ForwarderImplementation := CreateL2ForwarderImplementationCommand() + cmdViewL2ForwarderImplementation.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewL2ForwarderImplementation) + cmdViewL2ForwarderAddress := CreateL2ForwarderAddressCommand() + cmdViewL2ForwarderAddress.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewL2ForwarderAddress) + cmdViewL2ForwarderFactory := CreateL2ForwarderFactoryCommand() + cmdViewL2ForwarderFactory.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewL2ForwarderFactory) + cmdViewPaused := CreatePausedCommand() + cmdViewPaused.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewPaused) + cmdViewDEFAULTADMINROLE := CreateDefaultadminroleCommand() + cmdViewDEFAULTADMINROLE.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewDEFAULTADMINROLE) + cmdViewPAUSERROLE := CreatePauserroleCommand() + cmdViewPAUSERROLE.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewPAUSERROLE) + cmdViewBuildL2ForwarderParams := CreateBuildL2ForwarderParamsCommand() + cmdViewBuildL2ForwarderParams.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewBuildL2ForwarderParams) + cmdViewDetermineTypeAndFees := CreateDetermineTypeAndFeesCommand() + cmdViewDetermineTypeAndFees.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewDetermineTypeAndFees) + cmdViewGetRoleAdmin := CreateGetRoleAdminCommand() + cmdViewGetRoleAdmin.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewGetRoleAdmin) + cmdViewSupportsInterface := CreateSupportsInterfaceCommand() + cmdViewSupportsInterface.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewSupportsInterface) + + cmdTransactUnpause := CreateUnpauseCommand() + cmdTransactUnpause.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactUnpause) + cmdTransactGrantRole := CreateGrantRoleCommand() + cmdTransactGrantRole.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactGrantRole) + cmdTransactPause := CreatePauseCommand() + cmdTransactPause.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactPause) + cmdTransactRenounceRole := CreateRenounceRoleCommand() + cmdTransactRenounceRole.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactRenounceRole) + cmdTransactRevokeRole := CreateRevokeRoleCommand() + cmdTransactRevokeRole.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactRevokeRole) + cmdTransactTeleport := CreateTeleportCommand() + cmdTransactTeleport.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactTeleport) + + return cmd +} + diff --git a/bindings/L2ForwarderFactory/L2ForwarderFactory.go b/bindings/L2ForwarderFactory/L2ForwarderFactory.go new file mode 100644 index 0000000..f368ded --- /dev/null +++ b/bindings/L2ForwarderFactory/L2ForwarderFactory.go @@ -0,0 +1,1546 @@ +// This file was generated by seer: https://github.com/G7DAO/seer. +// seer version: 0.1.3 +// seer command: seer evm generate --package L2ForwarderFactory --cli --struct L2ForwarderFactory +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package L2ForwarderFactory + +import ( + "errors" + "math/big" + "strings" + + "context" + + 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. + "encoding/hex" + "encoding/json" + "fmt" + "os" + "time" + + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/spf13/cobra" + "golang.org/x/term" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// IL2ForwarderL2ForwarderParams is an auto generated low-level Go binding around an user-defined struct. +type IL2ForwarderL2ForwarderParams struct { + Owner common.Address + L2Token common.Address + L3FeeTokenL2Addr common.Address + RouterOrInbox common.Address + To common.Address + GasLimit *big.Int + GasPriceBid *big.Int + MaxSubmissionCost *big.Int + L3CallData []byte +} + +// L2ForwarderFactoryMetaData contains all meta data concerning the L2ForwarderFactory contract. +var L2ForwarderFactoryMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_impl\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_aliasedL1Teleporter\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"OnlyL1Teleporter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Forwarder\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l3FeeTokenL2Addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"routerOrInbox\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSubmissionCost\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"l3CallData\",\"type\":\"bytes\"}],\"indexed\":false,\"internalType\":\"structIL2Forwarder.L2ForwarderParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"CalledL2Forwarder\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"l2Forwarder\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"routerOrInbox\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"CreatedL2Forwarder\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"aliasedL1Teleporter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"l3FeeTokenL2Addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"routerOrInbox\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasPriceBid\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSubmissionCost\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"l3CallData\",\"type\":\"bytes\"}],\"internalType\":\"structIL2Forwarder.L2ForwarderParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"callForwarder\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"routerOrInbox\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"createL2Forwarder\",\"outputs\":[{\"internalType\":\"contractIL2Forwarder\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"routerOrInbox\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"l2ForwarderAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2ForwarderFactory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2ForwarderImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e060405234801561001057600080fd5b50604051610b01380380610b0183398101604081905261002f91610066565b306080526001600160a01b0391821660a0521660c052610099565b80516001600160a01b038116811461006157600080fd5b919050565b6000806040838503121561007957600080fd5b6100828361004a565b91506100906020840161004a565b90509250929050565b60805160a05160c051610a1e6100e36000396000818161010e0152610302015260008181610142015281816101de01526104bf01526000818160c501526104830152610a1e6000f3fe6080604052600436106100655760003560e01c8063e261911b11610043578063e261911b146100fc578063ec7d4abd14610130578063fbabf0841461016457600080fd5b806302e8e7831461006a578063377f017a146100b35780635b65a6a4146100e7575b600080fd5b34801561007657600080fd5b5061008a610085366004610662565b610184565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100bf57600080fd5b5061008a7f000000000000000000000000000000000000000000000000000000000000000081565b6100fa6100f53660046107a9565b6102ea565b005b34801561010857600080fd5b5061008a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561013c57600080fd5b5061008a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561017057600080fd5b5061008a61017f366004610662565b610432565b6040805173ffffffffffffffffffffffffffffffffffffffff8086166020808401919091528186168385015290841660608084019190915283518084039091018152608090920190925280519101206000908190610203907f000000000000000000000000000000000000000000000000000000000000000090610523565b6040517fc4d66de800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301529192509082169063c4d66de890602401600060405180830381600087803b15801561027057600080fd5b505af1158015610284573d6000803e3d6000fd5b50506040805173ffffffffffffffffffffffffffffffffffffffff88811682528781166020830152808a169450851692507f99f6b41137c463e01337801d2b5ee9d1b5d057e4266739a17a3d50d2149ef9be910160405180910390a390505b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610359576040517fbf801ce900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103728260000151836060015184608001516105f1565b90508073ffffffffffffffffffffffffffffffffffffffff1663cc617cd434846040518363ffffffff1660e01b81526004016103ae91906108f2565b6000604051808303818588803b1580156103c757600080fd5b505af11580156103db573d6000803e3d6000fd5b50505050508073ffffffffffffffffffffffffffffffffffffffff167fe7574670f76df54487060ea7a633529efd85f268c9bdf4b3142153c2330577128360405161042691906108f2565b60405180910390a25050565b6040805173ffffffffffffffffffffffffffffffffffffffff8581166020808401919091528582168385015290841660608084019190915283518084039091018152608083019384905280519101207f000000000000000000000000000000000000000000000000000000000000000060b88301526f5af43d82803e903d91602b57fd5bf3ff60a48301527f00000000000000000000000000000000000000000000000000000000000000006094830152733d602d80600a3d3981f3363d3d373d3d3d363d7390925260d88101919091526037608c82012060f8820152605560c3909101206000905b949350505050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008360601b60e81c176000526e5af43d82803e903d91602b57fd5bf38360781b1760205281603760096000f5905073ffffffffffffffffffffffffffffffffffffffff81166105eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f455243313136373a2063726561746532206661696c6564000000000000000000604482015260640160405180910390fd5b92915050565b6000806105ff858585610432565b905073ffffffffffffffffffffffffffffffffffffffff81163b156106255790506102e3565b610630858585610184565b95945050505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461065d57600080fd5b919050565b60008060006060848603121561067757600080fd5b61068084610639565b925061068e60208501610639565b915061069c60408501610639565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff811182821017156106f8576106f86106a5565b60405290565b600082601f83011261070f57600080fd5b813567ffffffffffffffff8082111561072a5761072a6106a5565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610770576107706106a5565b8160405283815286602085880101111561078957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000602082840312156107bb57600080fd5b813567ffffffffffffffff808211156107d357600080fd5b9083019061012082860312156107e857600080fd5b6107f06106d4565b6107f983610639565b815261080760208401610639565b602082015261081860408401610639565b604082015261082960608401610639565b606082015261083a60808401610639565b608082015260a083013560a082015260c083013560c082015260e083013560e0820152610100808401358381111561087157600080fd5b61087d888287016106fe565b918301919091525095945050505050565b6000815180845260005b818110156108b457602081850181015186830182015201610898565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815261091960208201835173ffffffffffffffffffffffffffffffffffffffff169052565b60006020830151610942604084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604083015173ffffffffffffffffffffffffffffffffffffffff8116606084015250606083015173ffffffffffffffffffffffffffffffffffffffff8116608084015250608083015173ffffffffffffffffffffffffffffffffffffffff811660a08401525060a083015160c083015260c083015160e083015260e083015161010081818501528085015191505061012080818501525061051b61014084018261088e56fea2646970667358221220ad0c58a910e71e1087a175dd2573e033f6996c3fd70caf754bbe437cb6835ce964736f6c63430008170033", +} + +// L2ForwarderFactoryABI is the input ABI used to generate the binding from. +// Deprecated: Use L2ForwarderFactoryMetaData.ABI instead. +var L2ForwarderFactoryABI = L2ForwarderFactoryMetaData.ABI + +// L2ForwarderFactoryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use L2ForwarderFactoryMetaData.Bin instead. +var L2ForwarderFactoryBin = L2ForwarderFactoryMetaData.Bin + +// DeployL2ForwarderFactory deploys a new Ethereum contract, binding an instance of L2ForwarderFactory to it. +func DeployL2ForwarderFactory(auth *bind.TransactOpts, backend bind.ContractBackend, _impl common.Address, _aliasedL1Teleporter common.Address) (common.Address, *types.Transaction, *L2ForwarderFactory, error) { + parsed, err := L2ForwarderFactoryMetaData.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(L2ForwarderFactoryBin), backend, _impl, _aliasedL1Teleporter) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &L2ForwarderFactory{L2ForwarderFactoryCaller: L2ForwarderFactoryCaller{contract: contract}, L2ForwarderFactoryTransactor: L2ForwarderFactoryTransactor{contract: contract}, L2ForwarderFactoryFilterer: L2ForwarderFactoryFilterer{contract: contract}}, nil +} + +// L2ForwarderFactory is an auto generated Go binding around an Ethereum contract. +type L2ForwarderFactory struct { + L2ForwarderFactoryCaller // Read-only binding to the contract + L2ForwarderFactoryTransactor // Write-only binding to the contract + L2ForwarderFactoryFilterer // Log filterer for contract events +} + +// L2ForwarderFactoryCaller is an auto generated read-only Go binding around an Ethereum contract. +type L2ForwarderFactoryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// L2ForwarderFactoryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type L2ForwarderFactoryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// L2ForwarderFactoryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type L2ForwarderFactoryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// L2ForwarderFactorySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type L2ForwarderFactorySession struct { + Contract *L2ForwarderFactory // 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 +} + +// L2ForwarderFactoryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type L2ForwarderFactoryCallerSession struct { + Contract *L2ForwarderFactoryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// L2ForwarderFactoryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type L2ForwarderFactoryTransactorSession struct { + Contract *L2ForwarderFactoryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// L2ForwarderFactoryRaw is an auto generated low-level Go binding around an Ethereum contract. +type L2ForwarderFactoryRaw struct { + Contract *L2ForwarderFactory // Generic contract binding to access the raw methods on +} + +// L2ForwarderFactoryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type L2ForwarderFactoryCallerRaw struct { + Contract *L2ForwarderFactoryCaller // Generic read-only contract binding to access the raw methods on +} + +// L2ForwarderFactoryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type L2ForwarderFactoryTransactorRaw struct { + Contract *L2ForwarderFactoryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewL2ForwarderFactory creates a new instance of L2ForwarderFactory, bound to a specific deployed contract. +func NewL2ForwarderFactory(address common.Address, backend bind.ContractBackend) (*L2ForwarderFactory, error) { + contract, err := bindL2ForwarderFactory(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &L2ForwarderFactory{L2ForwarderFactoryCaller: L2ForwarderFactoryCaller{contract: contract}, L2ForwarderFactoryTransactor: L2ForwarderFactoryTransactor{contract: contract}, L2ForwarderFactoryFilterer: L2ForwarderFactoryFilterer{contract: contract}}, nil +} + +// NewL2ForwarderFactoryCaller creates a new read-only instance of L2ForwarderFactory, bound to a specific deployed contract. +func NewL2ForwarderFactoryCaller(address common.Address, caller bind.ContractCaller) (*L2ForwarderFactoryCaller, error) { + contract, err := bindL2ForwarderFactory(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &L2ForwarderFactoryCaller{contract: contract}, nil +} + +// NewL2ForwarderFactoryTransactor creates a new write-only instance of L2ForwarderFactory, bound to a specific deployed contract. +func NewL2ForwarderFactoryTransactor(address common.Address, transactor bind.ContractTransactor) (*L2ForwarderFactoryTransactor, error) { + contract, err := bindL2ForwarderFactory(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &L2ForwarderFactoryTransactor{contract: contract}, nil +} + +// NewL2ForwarderFactoryFilterer creates a new log filterer instance of L2ForwarderFactory, bound to a specific deployed contract. +func NewL2ForwarderFactoryFilterer(address common.Address, filterer bind.ContractFilterer) (*L2ForwarderFactoryFilterer, error) { + contract, err := bindL2ForwarderFactory(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &L2ForwarderFactoryFilterer{contract: contract}, nil +} + +// bindL2ForwarderFactory binds a generic wrapper to an already deployed contract. +func bindL2ForwarderFactory(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := L2ForwarderFactoryMetaData.GetAbi() + 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 (_L2ForwarderFactory *L2ForwarderFactoryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _L2ForwarderFactory.Contract.L2ForwarderFactoryCaller.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 (_L2ForwarderFactory *L2ForwarderFactoryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _L2ForwarderFactory.Contract.L2ForwarderFactoryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_L2ForwarderFactory *L2ForwarderFactoryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _L2ForwarderFactory.Contract.L2ForwarderFactoryTransactor.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 (_L2ForwarderFactory *L2ForwarderFactoryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _L2ForwarderFactory.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 (_L2ForwarderFactory *L2ForwarderFactoryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _L2ForwarderFactory.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_L2ForwarderFactory *L2ForwarderFactoryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _L2ForwarderFactory.Contract.contract.Transact(opts, method, params...) +} + +// AliasedL1Teleporter is a free data retrieval call binding the contract method 0xe261911b. +// +// Solidity: function aliasedL1Teleporter() view returns(address) +func (_L2ForwarderFactory *L2ForwarderFactoryCaller) AliasedL1Teleporter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _L2ForwarderFactory.contract.Call(opts, &out, "aliasedL1Teleporter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// AliasedL1Teleporter is a free data retrieval call binding the contract method 0xe261911b. +// +// Solidity: function aliasedL1Teleporter() view returns(address) +func (_L2ForwarderFactory *L2ForwarderFactorySession) AliasedL1Teleporter() (common.Address, error) { + return _L2ForwarderFactory.Contract.AliasedL1Teleporter(&_L2ForwarderFactory.CallOpts) +} + +// AliasedL1Teleporter is a free data retrieval call binding the contract method 0xe261911b. +// +// Solidity: function aliasedL1Teleporter() view returns(address) +func (_L2ForwarderFactory *L2ForwarderFactoryCallerSession) AliasedL1Teleporter() (common.Address, error) { + return _L2ForwarderFactory.Contract.AliasedL1Teleporter(&_L2ForwarderFactory.CallOpts) +} + +// L2ForwarderAddress is a free data retrieval call binding the contract method 0xfbabf084. +// +// Solidity: function l2ForwarderAddress(address owner, address routerOrInbox, address to) view returns(address) +func (_L2ForwarderFactory *L2ForwarderFactoryCaller) L2ForwarderAddress(opts *bind.CallOpts, owner common.Address, routerOrInbox common.Address, to common.Address) (common.Address, error) { + var out []interface{} + err := _L2ForwarderFactory.contract.Call(opts, &out, "l2ForwarderAddress", owner, routerOrInbox, to) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// L2ForwarderAddress is a free data retrieval call binding the contract method 0xfbabf084. +// +// Solidity: function l2ForwarderAddress(address owner, address routerOrInbox, address to) view returns(address) +func (_L2ForwarderFactory *L2ForwarderFactorySession) L2ForwarderAddress(owner common.Address, routerOrInbox common.Address, to common.Address) (common.Address, error) { + return _L2ForwarderFactory.Contract.L2ForwarderAddress(&_L2ForwarderFactory.CallOpts, owner, routerOrInbox, to) +} + +// L2ForwarderAddress is a free data retrieval call binding the contract method 0xfbabf084. +// +// Solidity: function l2ForwarderAddress(address owner, address routerOrInbox, address to) view returns(address) +func (_L2ForwarderFactory *L2ForwarderFactoryCallerSession) L2ForwarderAddress(owner common.Address, routerOrInbox common.Address, to common.Address) (common.Address, error) { + return _L2ForwarderFactory.Contract.L2ForwarderAddress(&_L2ForwarderFactory.CallOpts, owner, routerOrInbox, to) +} + +// L2ForwarderFactory is a free data retrieval call binding the contract method 0x377f017a. +// +// Solidity: function l2ForwarderFactory() view returns(address) +func (_L2ForwarderFactory *L2ForwarderFactoryCaller) L2ForwarderFactory(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _L2ForwarderFactory.contract.Call(opts, &out, "l2ForwarderFactory") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// L2ForwarderFactory is a free data retrieval call binding the contract method 0x377f017a. +// +// Solidity: function l2ForwarderFactory() view returns(address) +func (_L2ForwarderFactory *L2ForwarderFactorySession) L2ForwarderFactory() (common.Address, error) { + return _L2ForwarderFactory.Contract.L2ForwarderFactory(&_L2ForwarderFactory.CallOpts) +} + +// L2ForwarderFactory is a free data retrieval call binding the contract method 0x377f017a. +// +// Solidity: function l2ForwarderFactory() view returns(address) +func (_L2ForwarderFactory *L2ForwarderFactoryCallerSession) L2ForwarderFactory() (common.Address, error) { + return _L2ForwarderFactory.Contract.L2ForwarderFactory(&_L2ForwarderFactory.CallOpts) +} + +// L2ForwarderImplementation is a free data retrieval call binding the contract method 0xec7d4abd. +// +// Solidity: function l2ForwarderImplementation() view returns(address) +func (_L2ForwarderFactory *L2ForwarderFactoryCaller) L2ForwarderImplementation(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _L2ForwarderFactory.contract.Call(opts, &out, "l2ForwarderImplementation") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// L2ForwarderImplementation is a free data retrieval call binding the contract method 0xec7d4abd. +// +// Solidity: function l2ForwarderImplementation() view returns(address) +func (_L2ForwarderFactory *L2ForwarderFactorySession) L2ForwarderImplementation() (common.Address, error) { + return _L2ForwarderFactory.Contract.L2ForwarderImplementation(&_L2ForwarderFactory.CallOpts) +} + +// L2ForwarderImplementation is a free data retrieval call binding the contract method 0xec7d4abd. +// +// Solidity: function l2ForwarderImplementation() view returns(address) +func (_L2ForwarderFactory *L2ForwarderFactoryCallerSession) L2ForwarderImplementation() (common.Address, error) { + return _L2ForwarderFactory.Contract.L2ForwarderImplementation(&_L2ForwarderFactory.CallOpts) +} + +// CallForwarder is a paid mutator transaction binding the contract method 0x5b65a6a4. +// +// Solidity: function callForwarder((address,address,address,address,address,uint256,uint256,uint256,bytes) params) payable returns() +func (_L2ForwarderFactory *L2ForwarderFactoryTransactor) CallForwarder(opts *bind.TransactOpts, params IL2ForwarderL2ForwarderParams) (*types.Transaction, error) { + return _L2ForwarderFactory.contract.Transact(opts, "callForwarder", params) +} + +// CallForwarder is a paid mutator transaction binding the contract method 0x5b65a6a4. +// +// Solidity: function callForwarder((address,address,address,address,address,uint256,uint256,uint256,bytes) params) payable returns() +func (_L2ForwarderFactory *L2ForwarderFactorySession) CallForwarder(params IL2ForwarderL2ForwarderParams) (*types.Transaction, error) { + return _L2ForwarderFactory.Contract.CallForwarder(&_L2ForwarderFactory.TransactOpts, params) +} + +// CallForwarder is a paid mutator transaction binding the contract method 0x5b65a6a4. +// +// Solidity: function callForwarder((address,address,address,address,address,uint256,uint256,uint256,bytes) params) payable returns() +func (_L2ForwarderFactory *L2ForwarderFactoryTransactorSession) CallForwarder(params IL2ForwarderL2ForwarderParams) (*types.Transaction, error) { + return _L2ForwarderFactory.Contract.CallForwarder(&_L2ForwarderFactory.TransactOpts, params) +} + +// CreateL2Forwarder is a paid mutator transaction binding the contract method 0x02e8e783. +// +// Solidity: function createL2Forwarder(address owner, address routerOrInbox, address to) returns(address) +func (_L2ForwarderFactory *L2ForwarderFactoryTransactor) CreateL2Forwarder(opts *bind.TransactOpts, owner common.Address, routerOrInbox common.Address, to common.Address) (*types.Transaction, error) { + return _L2ForwarderFactory.contract.Transact(opts, "createL2Forwarder", owner, routerOrInbox, to) +} + +// CreateL2Forwarder is a paid mutator transaction binding the contract method 0x02e8e783. +// +// Solidity: function createL2Forwarder(address owner, address routerOrInbox, address to) returns(address) +func (_L2ForwarderFactory *L2ForwarderFactorySession) CreateL2Forwarder(owner common.Address, routerOrInbox common.Address, to common.Address) (*types.Transaction, error) { + return _L2ForwarderFactory.Contract.CreateL2Forwarder(&_L2ForwarderFactory.TransactOpts, owner, routerOrInbox, to) +} + +// CreateL2Forwarder is a paid mutator transaction binding the contract method 0x02e8e783. +// +// Solidity: function createL2Forwarder(address owner, address routerOrInbox, address to) returns(address) +func (_L2ForwarderFactory *L2ForwarderFactoryTransactorSession) CreateL2Forwarder(owner common.Address, routerOrInbox common.Address, to common.Address) (*types.Transaction, error) { + return _L2ForwarderFactory.Contract.CreateL2Forwarder(&_L2ForwarderFactory.TransactOpts, owner, routerOrInbox, to) +} + +// L2ForwarderFactoryCalledL2ForwarderIterator is returned from FilterCalledL2Forwarder and is used to iterate over the raw logs and unpacked data for CalledL2Forwarder events raised by the L2ForwarderFactory contract. +type L2ForwarderFactoryCalledL2ForwarderIterator struct { + Event *L2ForwarderFactoryCalledL2Forwarder // 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 *L2ForwarderFactoryCalledL2ForwarderIterator) 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(L2ForwarderFactoryCalledL2Forwarder) + 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(L2ForwarderFactoryCalledL2Forwarder) + 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 *L2ForwarderFactoryCalledL2ForwarderIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *L2ForwarderFactoryCalledL2ForwarderIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// L2ForwarderFactoryCalledL2Forwarder represents a CalledL2Forwarder event raised by the L2ForwarderFactory contract. +type L2ForwarderFactoryCalledL2Forwarder struct { + L2Forwarder common.Address + Params IL2ForwarderL2ForwarderParams + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCalledL2Forwarder is a free log retrieval operation binding the contract event 0xe7574670f76df54487060ea7a633529efd85f268c9bdf4b3142153c233057712. +// +// Solidity: event CalledL2Forwarder(address indexed l2Forwarder, (address,address,address,address,address,uint256,uint256,uint256,bytes) params) +func (_L2ForwarderFactory *L2ForwarderFactoryFilterer) FilterCalledL2Forwarder(opts *bind.FilterOpts, l2Forwarder []common.Address) (*L2ForwarderFactoryCalledL2ForwarderIterator, error) { + + var l2ForwarderRule []interface{} + for _, l2ForwarderItem := range l2Forwarder { + l2ForwarderRule = append(l2ForwarderRule, l2ForwarderItem) + } + + logs, sub, err := _L2ForwarderFactory.contract.FilterLogs(opts, "CalledL2Forwarder", l2ForwarderRule) + if err != nil { + return nil, err + } + return &L2ForwarderFactoryCalledL2ForwarderIterator{contract: _L2ForwarderFactory.contract, event: "CalledL2Forwarder", logs: logs, sub: sub}, nil +} + +// WatchCalledL2Forwarder is a free log subscription operation binding the contract event 0xe7574670f76df54487060ea7a633529efd85f268c9bdf4b3142153c233057712. +// +// Solidity: event CalledL2Forwarder(address indexed l2Forwarder, (address,address,address,address,address,uint256,uint256,uint256,bytes) params) +func (_L2ForwarderFactory *L2ForwarderFactoryFilterer) WatchCalledL2Forwarder(opts *bind.WatchOpts, sink chan<- *L2ForwarderFactoryCalledL2Forwarder, l2Forwarder []common.Address) (event.Subscription, error) { + + var l2ForwarderRule []interface{} + for _, l2ForwarderItem := range l2Forwarder { + l2ForwarderRule = append(l2ForwarderRule, l2ForwarderItem) + } + + logs, sub, err := _L2ForwarderFactory.contract.WatchLogs(opts, "CalledL2Forwarder", l2ForwarderRule) + 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(L2ForwarderFactoryCalledL2Forwarder) + if err := _L2ForwarderFactory.contract.UnpackLog(event, "CalledL2Forwarder", 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 +} + +// ParseCalledL2Forwarder is a log parse operation binding the contract event 0xe7574670f76df54487060ea7a633529efd85f268c9bdf4b3142153c233057712. +// +// Solidity: event CalledL2Forwarder(address indexed l2Forwarder, (address,address,address,address,address,uint256,uint256,uint256,bytes) params) +func (_L2ForwarderFactory *L2ForwarderFactoryFilterer) ParseCalledL2Forwarder(log types.Log) (*L2ForwarderFactoryCalledL2Forwarder, error) { + event := new(L2ForwarderFactoryCalledL2Forwarder) + if err := _L2ForwarderFactory.contract.UnpackLog(event, "CalledL2Forwarder", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// L2ForwarderFactoryCreatedL2ForwarderIterator is returned from FilterCreatedL2Forwarder and is used to iterate over the raw logs and unpacked data for CreatedL2Forwarder events raised by the L2ForwarderFactory contract. +type L2ForwarderFactoryCreatedL2ForwarderIterator struct { + Event *L2ForwarderFactoryCreatedL2Forwarder // 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 *L2ForwarderFactoryCreatedL2ForwarderIterator) 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(L2ForwarderFactoryCreatedL2Forwarder) + 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(L2ForwarderFactoryCreatedL2Forwarder) + 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 *L2ForwarderFactoryCreatedL2ForwarderIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *L2ForwarderFactoryCreatedL2ForwarderIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// L2ForwarderFactoryCreatedL2Forwarder represents a CreatedL2Forwarder event raised by the L2ForwarderFactory contract. +type L2ForwarderFactoryCreatedL2Forwarder struct { + L2Forwarder common.Address + Owner common.Address + RouterOrInbox common.Address + To common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCreatedL2Forwarder is a free log retrieval operation binding the contract event 0x99f6b41137c463e01337801d2b5ee9d1b5d057e4266739a17a3d50d2149ef9be. +// +// Solidity: event CreatedL2Forwarder(address indexed l2Forwarder, address indexed owner, address routerOrInbox, address to) +func (_L2ForwarderFactory *L2ForwarderFactoryFilterer) FilterCreatedL2Forwarder(opts *bind.FilterOpts, l2Forwarder []common.Address, owner []common.Address) (*L2ForwarderFactoryCreatedL2ForwarderIterator, error) { + + var l2ForwarderRule []interface{} + for _, l2ForwarderItem := range l2Forwarder { + l2ForwarderRule = append(l2ForwarderRule, l2ForwarderItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _L2ForwarderFactory.contract.FilterLogs(opts, "CreatedL2Forwarder", l2ForwarderRule, ownerRule) + if err != nil { + return nil, err + } + return &L2ForwarderFactoryCreatedL2ForwarderIterator{contract: _L2ForwarderFactory.contract, event: "CreatedL2Forwarder", logs: logs, sub: sub}, nil +} + +// WatchCreatedL2Forwarder is a free log subscription operation binding the contract event 0x99f6b41137c463e01337801d2b5ee9d1b5d057e4266739a17a3d50d2149ef9be. +// +// Solidity: event CreatedL2Forwarder(address indexed l2Forwarder, address indexed owner, address routerOrInbox, address to) +func (_L2ForwarderFactory *L2ForwarderFactoryFilterer) WatchCreatedL2Forwarder(opts *bind.WatchOpts, sink chan<- *L2ForwarderFactoryCreatedL2Forwarder, l2Forwarder []common.Address, owner []common.Address) (event.Subscription, error) { + + var l2ForwarderRule []interface{} + for _, l2ForwarderItem := range l2Forwarder { + l2ForwarderRule = append(l2ForwarderRule, l2ForwarderItem) + } + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + logs, sub, err := _L2ForwarderFactory.contract.WatchLogs(opts, "CreatedL2Forwarder", l2ForwarderRule, ownerRule) + 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(L2ForwarderFactoryCreatedL2Forwarder) + if err := _L2ForwarderFactory.contract.UnpackLog(event, "CreatedL2Forwarder", 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 +} + +// ParseCreatedL2Forwarder is a log parse operation binding the contract event 0x99f6b41137c463e01337801d2b5ee9d1b5d057e4266739a17a3d50d2149ef9be. +// +// Solidity: event CreatedL2Forwarder(address indexed l2Forwarder, address indexed owner, address routerOrInbox, address to) +func (_L2ForwarderFactory *L2ForwarderFactoryFilterer) ParseCreatedL2Forwarder(log types.Log) (*L2ForwarderFactoryCreatedL2Forwarder, error) { + event := new(L2ForwarderFactoryCreatedL2Forwarder) + if err := _L2ForwarderFactory.contract.UnpackLog(event, "CreatedL2Forwarder", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func CreateL2ForwarderFactoryDeploymentCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc string + var gasLimit uint64 + var simulate bool + var timeout uint + + var impl common.Address + var implRaw string + var aliasedL1Teleporter common.Address + var aliasedL1TeleporterRaw string + + cmd := &cobra.Command{ + Use: "deploy", + Short: "Deploy a new L2ForwarderFactory contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if implRaw == "" { + return fmt.Errorf("--impl argument not specified") + } else if !common.IsHexAddress(implRaw) { + return fmt.Errorf("--impl argument is not a valid Ethereum address") + } + impl = common.HexToAddress(implRaw) + + if aliasedL1TeleporterRaw == "" { + return fmt.Errorf("--aliased-l-1-teleporter argument not specified") + } else if !common.IsHexAddress(aliasedL1TeleporterRaw) { + return fmt.Errorf("--aliased-l-1-teleporter argument is not a valid Ethereum address") + } + aliasedL1Teleporter = common.HexToAddress(aliasedL1TeleporterRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + address, deploymentTransaction, _, deploymentErr := DeployL2ForwarderFactory( + transactionOpts, + client, + impl, + aliasedL1Teleporter, + ) + if deploymentErr != nil { + return deploymentErr + } + + cmd.Printf("Transaction hash: %s\nContract address: %s\n", deploymentTransaction.Hash().Hex(), address.Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + Data: deploymentTransaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := deploymentTransaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + + cmd.Flags().StringVar(&implRaw, "impl", "", "impl argument") + cmd.Flags().StringVar(&aliasedL1TeleporterRaw, "aliased-l-1-teleporter", "", "aliased-l-1-teleporter argument") + + return cmd +} + +func CreateAliasedL1TeleporterCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "aliased-l-1-teleporter", + Short: "Call the AliasedL1Teleporter view method on a L2ForwarderFactory contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL2ForwarderFactory(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L2ForwarderFactoryCallerSession{ + Contract: &contract.L2ForwarderFactoryCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.AliasedL1Teleporter() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateL2ForwarderAddressCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var owner common.Address + var ownerRaw string + var routerOrInbox common.Address + var routerOrInboxRaw string + var to0 common.Address + var to0Raw string + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "l-2-forwarder-address", + Short: "Call the L2ForwarderAddress view method on a L2ForwarderFactory contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if ownerRaw == "" { + return fmt.Errorf("--owner argument not specified") + } else if !common.IsHexAddress(ownerRaw) { + return fmt.Errorf("--owner argument is not a valid Ethereum address") + } + owner = common.HexToAddress(ownerRaw) + + if routerOrInboxRaw == "" { + return fmt.Errorf("--router-or-inbox argument not specified") + } else if !common.IsHexAddress(routerOrInboxRaw) { + return fmt.Errorf("--router-or-inbox argument is not a valid Ethereum address") + } + routerOrInbox = common.HexToAddress(routerOrInboxRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL2ForwarderFactory(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L2ForwarderFactoryCallerSession{ + Contract: &contract.L2ForwarderFactoryCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.L2ForwarderAddress( + owner, + routerOrInbox, + to0, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().StringVar(&ownerRaw, "owner", "", "owner argument") + cmd.Flags().StringVar(&routerOrInboxRaw, "router-or-inbox", "", "router-or-inbox argument") + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument") + + return cmd +} +func CreateL2ForwarderFactoryCommand2() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "l-2-forwarder-factory", + Short: "Call the L2ForwarderFactory view method on a L2ForwarderFactory contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL2ForwarderFactory(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L2ForwarderFactoryCallerSession{ + Contract: &contract.L2ForwarderFactoryCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.L2ForwarderFactory() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateL2ForwarderImplementationCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "l-2-forwarder-implementation", + Short: "Call the L2ForwarderImplementation view method on a L2ForwarderFactory contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewL2ForwarderFactory(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := L2ForwarderFactoryCallerSession{ + Contract: &contract.L2ForwarderFactoryCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.L2ForwarderImplementation() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} + +func CreateCallForwarderCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var params IL2ForwarderL2ForwarderParams + var paramsRaw string + + cmd := &cobra.Command{ + Use: "call-forwarder", + Short: "Execute the CallForwarder method on a L2ForwarderFactory contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if paramsRaw == "" { + return fmt.Errorf("--params argument not specified") + } else if strings.HasPrefix(paramsRaw, "@") { + filename := strings.TrimPrefix(paramsRaw, "@") + contents, readErr := os.ReadFile(filename) + if readErr != nil { + return readErr + } + unmarshalErr := json.Unmarshal(contents, ¶ms) + if unmarshalErr != nil { + return unmarshalErr + } + } else { + unmarshalErr := json.Unmarshal([]byte(paramsRaw), ¶ms) + if unmarshalErr != nil { + return unmarshalErr + } + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewL2ForwarderFactory(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := L2ForwarderFactoryTransactorSession{ + Contract: &contract.L2ForwarderFactoryTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.CallForwarder( + params, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(¶msRaw, "params", "", "params argument") + + return cmd +} +func CreateCreateL2ForwarderCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + + var owner common.Address + var ownerRaw string + var routerOrInbox common.Address + var routerOrInboxRaw string + var to0 common.Address + var to0Raw string + + cmd := &cobra.Command{ + Use: "create-l-2-forwarder", + Short: "Execute the CreateL2Forwarder method on a L2ForwarderFactory contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if keyfile == "" { + return fmt.Errorf("--keystore not specified") + } + + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if ownerRaw == "" { + return fmt.Errorf("--owner argument not specified") + } else if !common.IsHexAddress(ownerRaw) { + return fmt.Errorf("--owner argument is not a valid Ethereum address") + } + owner = common.HexToAddress(ownerRaw) + + if routerOrInboxRaw == "" { + return fmt.Errorf("--router-or-inbox argument not specified") + } else if !common.IsHexAddress(routerOrInboxRaw) { + return fmt.Errorf("--router-or-inbox argument is not a valid Ethereum address") + } + routerOrInbox = common.HexToAddress(routerOrInboxRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewL2ForwarderFactory(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := L2ForwarderFactoryTransactorSession{ + Contract: &contract.L2ForwarderFactoryTransactor, + TransactOpts: *transactionOpts, + } + + transaction, transactionErr := session.CreateL2Forwarder( + owner, + routerOrInbox, + to0, + ) + if transactionErr != nil { + return transactionErr + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + + cmd.Flags().StringVar(&ownerRaw, "owner", "", "owner argument") + cmd.Flags().StringVar(&routerOrInboxRaw, "router-or-inbox", "", "router-or-inbox argument") + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument") + + return cmd +} + +var ErrNoRPCURL error = errors.New("no RPC URL provided -- please pass an RPC URL from the command line or set the L_2_FORWARDER_FACTORY_RPC_URL environment variable") + +// Generates an Ethereum client to the JSONRPC API at the given URL. If rpcURL is empty, then it +// attempts to read the RPC URL from the L_2_FORWARDER_FACTORY_RPC_URL environment variable. If that is empty, +// too, then it returns an error. +func NewClient(rpcURL string) (*ethclient.Client, error) { + if rpcURL == "" { + rpcURL = os.Getenv("L_2_FORWARDER_FACTORY_RPC_URL") + } + + if rpcURL == "" { + return nil, ErrNoRPCURL + } + + client, err := ethclient.Dial(rpcURL) + return client, err +} + +// Creates a new context to be used when interacting with the chain client. +func NewChainContext(timeout uint) (context.Context, context.CancelFunc) { + baseCtx := context.Background() + parsedTimeout := time.Duration(timeout) * time.Second + ctx, cancel := context.WithTimeout(baseCtx, parsedTimeout) + return ctx, cancel +} + +// Unlocks a key from a keystore (byte contents of a keystore file) with the given password. +func UnlockKeystore(keystoreData []byte, password string) (*keystore.Key, error) { + key, err := keystore.DecryptKey(keystoreData, password) + return key, err +} + +// Loads a key from file, prompting the user for the password if it is not provided as a function argument. +func KeyFromFile(keystoreFile string, password string) (*keystore.Key, error) { + var emptyKey *keystore.Key + keystoreContent, readErr := os.ReadFile(keystoreFile) + if readErr != nil { + return emptyKey, readErr + } + + // If password is "", prompt user for password. + if password == "" { + fmt.Printf("Please provide a password for keystore (%s): ", keystoreFile) + passwordRaw, inputErr := term.ReadPassword(int(os.Stdin.Fd())) + if inputErr != nil { + return emptyKey, fmt.Errorf("error reading password: %s", inputErr.Error()) + } + fmt.Print("\n") + password = string(passwordRaw) + } + + key, err := UnlockKeystore(keystoreContent, password) + return key, err +} + +// This method is used to set the parameters on a view call from command line arguments (represented mostly as +// strings). +func SetCallParametersFromArgs(opts *bind.CallOpts, pending bool, fromAddress, blockNumber string) { + if pending { + opts.Pending = true + } + + if fromAddress != "" { + opts.From = common.HexToAddress(fromAddress) + } + + if blockNumber != "" { + opts.BlockNumber = new(big.Int) + opts.BlockNumber.SetString(blockNumber, 0) + } +} + +// This method is used to set the parameters on a transaction from command line arguments (represented mostly as +// strings). +func SetTransactionParametersFromArgs(opts *bind.TransactOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas string, gasLimit uint64, noSend bool) { + if nonce != "" { + opts.Nonce = new(big.Int) + opts.Nonce.SetString(nonce, 0) + } + + if value != "" { + opts.Value = new(big.Int) + opts.Value.SetString(value, 0) + } + + if gasPrice != "" { + opts.GasPrice = new(big.Int) + opts.GasPrice.SetString(gasPrice, 0) + } + + if maxFeePerGas != "" { + opts.GasFeeCap = new(big.Int) + opts.GasFeeCap.SetString(maxFeePerGas, 0) + } + + if maxPriorityFeePerGas != "" { + opts.GasTipCap = new(big.Int) + opts.GasTipCap.SetString(maxPriorityFeePerGas, 0) + } + + if gasLimit != 0 { + opts.GasLimit = gasLimit + } + + opts.NoSend = noSend +} + +func CreateL2ForwarderFactoryCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "l-2-forwarder-factory", + Short: "Interact with the L2ForwarderFactory contract", + Run: func(cmd *cobra.Command, args []string) { + cmd.Help() + }, + } + + cmd.SetOut(os.Stdout) + + DeployGroup := &cobra.Group{ + ID: "deploy", Title: "Commands which deploy contracts", + } + cmd.AddGroup(DeployGroup) + ViewGroup := &cobra.Group{ + ID: "view", Title: "Commands which view contract state", + } + TransactGroup := &cobra.Group{ + ID: "transact", Title: "Commands which submit transactions", + } + cmd.AddGroup(ViewGroup, TransactGroup) + + cmdDeployL2ForwarderFactory := CreateL2ForwarderFactoryDeploymentCommand() + cmdDeployL2ForwarderFactory.GroupID = DeployGroup.ID + cmd.AddCommand(cmdDeployL2ForwarderFactory) + + cmdViewAliasedL1Teleporter := CreateAliasedL1TeleporterCommand() + cmdViewAliasedL1Teleporter.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewAliasedL1Teleporter) + cmdViewL2ForwarderAddress := CreateL2ForwarderAddressCommand() + cmdViewL2ForwarderAddress.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewL2ForwarderAddress) + cmdViewL2ForwarderFactory := CreateL2ForwarderFactoryCommand() + cmdViewL2ForwarderFactory.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewL2ForwarderFactory) + cmdViewL2ForwarderImplementation := CreateL2ForwarderImplementationCommand() + cmdViewL2ForwarderImplementation.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewL2ForwarderImplementation) + + cmdTransactCallForwarder := CreateCallForwarderCommand() + cmdTransactCallForwarder.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactCallForwarder) + cmdTransactCreateL2Forwarder := CreateCreateL2ForwarderCommand() + cmdTransactCreateL2Forwarder.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactCreateL2Forwarder) + + return cmd +} + diff --git a/cmd/arbitrum/bridge.go b/cmd/arbitrum/bridge.go index dd62b35..96308e3 100644 --- a/cmd/arbitrum/bridge.go +++ b/cmd/arbitrum/bridge.go @@ -7,7 +7,9 @@ import ( "os" "strings" + "github.com/G7DAO/bifrost/bindings/ArbitrumL1OrbitCustomGateway" "github.com/G7DAO/bifrost/bindings/ERC20Inbox" + "github.com/G7DAO/bifrost/bindings/L1GatewayRouter" "github.com/G7DAO/bifrost/bindings/NodeInterface" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -121,3 +123,164 @@ func NativeTokenBridgePropose(inboxAddress common.Address, keyFile string, passw return CreateSafeProposal(l1Client, key, safeAddress, inboxAddress, createRetryableTicketData, big.NewInt(0), safeApi, OperationType(safeOperation), safeNonce) } + +func GetERC20BridgeCalldataAndValue(routerAddress common.Address, key *keystore.Key, l1Rpc string, l2Rpc string, tokenAddress common.Address, to common.Address, amount *big.Int) ([]byte, *big.Int, error) { + l1Client, l1ClientErr := ethclient.DialContext(context.Background(), l1Rpc) + if l1ClientErr != nil { + fmt.Fprintln(os.Stderr, "l1ClientErr", l1ClientErr.Error()) + return nil, nil, l1ClientErr + } + + l2Client, l2ClientErr := ethclient.DialContext(context.Background(), l2Rpc) + if l2ClientErr != nil { + fmt.Fprintln(os.Stderr, "l2ClientErr", l2ClientErr.Error()) + return nil, nil, l2ClientErr + } + + gasPriceBid, gasPriceBidErr := l1Client.SuggestGasPrice(context.Background()) + if gasPriceBidErr != nil { + fmt.Fprintln(os.Stderr, "gasPriceBidErr", gasPriceBidErr.Error()) + return nil, nil, gasPriceBidErr + } + + router, routerErr := L1GatewayRouter.NewL1GatewayRouter(routerAddress, l1Client) + if routerErr != nil { + fmt.Fprintln(os.Stderr, "routerErr", routerErr.Error()) + return nil, nil, routerErr + } + + outboundCalldata, outboundCalldataErr := router.GetOutboundCalldata(nil, tokenAddress, key.Address, to, amount, []byte{}) + if outboundCalldataErr != nil { + fmt.Fprintln(os.Stderr, "outboundCalldataErr", outboundCalldataErr.Error()) + return nil, nil, outboundCalldataErr + } + + gatewayAddress, gatewayAddressErr := router.GetGateway(nil, tokenAddress) + if gatewayAddressErr != nil { + return nil, nil, gatewayAddressErr + } + + gateway, gatewayErr := ArbitrumL1OrbitCustomGateway.NewL1OrbitCustomGateway(gatewayAddress, l1Client) + if gatewayErr != nil { + return nil, nil, gatewayErr + } + + // Source: https://github.com/OffchainLabs/arbitrum-sdk/blob/0da65020438fc3e46728ea182f1b4dcf04e3cb7f/src/lib/message/L1ToL2MessageGasEstimator.ts#L154 + senderDeposit := big.NewInt(0).Add(big.NewInt(0), ONE_ETHER) + counterpartGatewayAddress, counterpartGatewayAddressErr := gateway.CounterpartGateway(nil) + if counterpartGatewayAddressErr != nil { + return nil, nil, counterpartGatewayAddressErr + } + + gasLimit, gasLimitErr := CalculateRetryableGasLimit(l2Client, gatewayAddress, senderDeposit, counterpartGatewayAddress, big.NewInt(0), to, RemapL1Address(key.Address), outboundCalldata) + if gasLimitErr != nil { + fmt.Fprintln(os.Stderr, "gasLimitErr", gasLimitErr.Error()) + return nil, nil, gasLimitErr + } + maxGas := big.NewInt(0).SetUint64(gasLimit) + + maxSubmissionCost, maxSubmissionCostErr := CalculateRetryableSubmissionFee(outboundCalldata, gasPriceBid) + if maxSubmissionCostErr != nil { + fmt.Fprintln(os.Stderr, "maxSubmissionCostErr", maxSubmissionCostErr.Error()) + return nil, nil, maxSubmissionCostErr + } + + executionCost := big.NewInt(0).Mul(maxGas, gasPriceBid) + tokenTotalFeeAmount := big.NewInt(0).Add(maxSubmissionCost, executionCost) + tokenTotalFeeAmount.Add(tokenTotalFeeAmount, big.NewInt(0)) + + // Encode (uint256 maxSubmissionCost, bytes callHookData, uint256 tokenTotalFeeAmount) + arguments := abi.Arguments{ + {Type: abi.Type{T: abi.UintTy, Size: 256}}, + {Type: abi.Type{T: abi.BytesTy}}, + {Type: abi.Type{T: abi.UintTy, Size: 256}}, + } + data, dataErr := arguments.Pack(maxSubmissionCost, []byte{}, tokenTotalFeeAmount) + if dataErr != nil { + fmt.Fprintln(os.Stderr, "dataErr", dataErr.Error()) + return nil, nil, dataErr + } + + routerAbi, routerAbiErr := abi.JSON(strings.NewReader(L1GatewayRouter.L1GatewayRouterABI)) + if routerAbiErr != nil { + fmt.Fprintln(os.Stderr, "routerAbiErr", routerAbiErr.Error()) + return nil, nil, routerAbiErr + } + + callData, callDataErr := routerAbi.Pack("outboundTransfer", tokenAddress, to, amount, maxGas, gasPriceBid, data) + if callDataErr != nil { + fmt.Fprintln(os.Stderr, "callDataErr", callDataErr.Error()) + return nil, nil, callDataErr + } + + return callData, tokenTotalFeeAmount, nil +} + +func ERC20BridgeCall(routerAddress common.Address, keyFile string, password string, l1Rpc string, l2Rpc string, tokenAddress common.Address, to common.Address, amount *big.Int, customNativeToken bool) (*types.Transaction, error) { + key, keyErr := NodeInterface.KeyFromFile(keyFile, password) + if keyErr != nil { + fmt.Fprintln(os.Stderr, "keyErr", keyErr.Error()) + return nil, keyErr + } + + callData, tokenTotalFeeAmount, callDataErr := GetERC20BridgeCalldataAndValue(routerAddress, key, l1Rpc, l2Rpc, tokenAddress, to, amount) + if callDataErr != nil { + fmt.Fprintln(os.Stderr, "callDataErr", callDataErr.Error()) + return nil, callDataErr + } + + l1Client, l1ClientErr := ethclient.DialContext(context.Background(), l1Rpc) + if l1ClientErr != nil { + fmt.Fprintln(os.Stderr, "l1ClientErr", l1ClientErr.Error()) + return nil, l1ClientErr + } + + fmt.Println(key.Address.Hex()) + + fmt.Println("Sending transaction...") + if customNativeToken { + tokenTotalFeeAmount = big.NewInt(0) + } + transaction, transactionErr := SendTransaction(l1Client, key, password, callData, routerAddress.Hex(), tokenTotalFeeAmount) + if transactionErr != nil { + fmt.Fprintln(os.Stderr, "transactionErr", transactionErr.Error()) + return nil, transactionErr + } + fmt.Println("Transaction sent! Transaction hash:", transaction.Hash().Hex()) + + fmt.Println("Waiting for transaction to be mined...") + _, receiptErr := bind.WaitMined(context.Background(), l1Client, transaction) + if receiptErr != nil { + fmt.Fprintln(os.Stderr, "receiptErr", receiptErr.Error()) + return nil, receiptErr + } + fmt.Println("Transaction mined!") + + return transaction, nil +} + +func ERC20BridgePropose(routerAddress common.Address, keyFile string, password string, l1Rpc string, l2Rpc string, tokenAddress common.Address, to common.Address, amount *big.Int, safeAddress common.Address, safeApi string, safeOperation uint8, safeNonce *big.Int, customNativeToken bool) error { + key, keyErr := NodeInterface.KeyFromFile(keyFile, password) + if keyErr != nil { + fmt.Fprintln(os.Stderr, "keyErr", keyErr.Error()) + return keyErr + } + + callData, tokenTotalFeeAmount, callDataErr := GetERC20BridgeCalldataAndValue(routerAddress, key, l1Rpc, l2Rpc, tokenAddress, to, amount) + if callDataErr != nil { + fmt.Fprintln(os.Stderr, "callDataErr", callDataErr.Error()) + return callDataErr + } + + l1Client, l1ClientErr := ethclient.DialContext(context.Background(), l1Rpc) + if l1ClientErr != nil { + fmt.Fprintln(os.Stderr, "l1ClientErr", l1ClientErr.Error()) + return l1ClientErr + } + + if customNativeToken { + tokenTotalFeeAmount = big.NewInt(0) + } + + return CreateSafeProposal(l1Client, key, safeAddress, routerAddress, callData, tokenTotalFeeAmount, safeApi, OperationType(safeOperation), safeNonce) +} diff --git a/cmd/arbitrum/bridgeCmd.go b/cmd/arbitrum/bridgeCmd.go new file mode 100644 index 0000000..d1e1439 --- /dev/null +++ b/cmd/arbitrum/bridgeCmd.go @@ -0,0 +1,405 @@ +package arbitrum_bifrost + +import ( + "context" + "encoding/hex" + "errors" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/spf13/cobra" +) + +func CreateArbitrumBridgeCommand() *cobra.Command { + bridgeCmd := &cobra.Command{ + Use: "bridge", + Short: "Bridge tokens between chains", + Run: func(cmd *cobra.Command, args []string) { + cmd.Help() + }, + } + + bridgeCmd.AddCommand(CreateBridgeNativeTokenCommand()) + bridgeCmd.AddCommand(CreateBridgeERC20Command()) + + return bridgeCmd +} + +func CreateBridgeNativeTokenCommand() *cobra.Command { + nativeTokenCmd := &cobra.Command{ + Use: "native-token", + Short: "Bridge native tokens between chains", + Run: func(cmd *cobra.Command, args []string) { + cmd.Help() + }, + } + + nativeTokenCmd.AddCommand(CreateBridgeNativeTokenL1ToL2Command()) + nativeTokenCmd.AddCommand(CreateBridgeNativeTokenL1ToL3Command()) + + return nativeTokenCmd +} + +func CreateBridgeNativeTokenL1ToL2Command() *cobra.Command { + var keyFile, password, l1Rpc, l2Rpc, inboxRaw, toRaw, l2CallValueRaw, l2CalldataRaw, safeAddressRaw, safeApi, safeNonceRaw string + var inboxAddress, to, safeAddress common.Address + var l2CallValue *big.Int + var l2Calldata []byte + var safeOperation uint8 + var safeNonce *big.Int + + createCmd := &cobra.Command{ + Use: "l1-to-l2", + Short: "Bridge tokens from L1 to L2", + Long: `Bridge tokens from L1 to L2 with a single transaction and arbitrary calldata`, + + PreRunE: func(cmd *cobra.Command, args []string) error { + if !common.IsHexAddress(inboxRaw) { + return errors.New("invalid inbox address") + } + inboxAddress = common.HexToAddress(inboxRaw) + + if !common.IsHexAddress(toRaw) { + return errors.New("invalid recipient address") + } + to = common.HexToAddress(toRaw) + + l2CallValue = new(big.Int) + if l2CallValueRaw != "" { + _, ok := l2CallValue.SetString(l2CallValueRaw, 10) + if !ok { + return errors.New("invalid L2 call value") + } + } else { + fmt.Println("No L2 call value provided, defaulting to 0") + l2CallValue.SetInt64(0) + } + + if l2CalldataRaw != "" { + var err error + l2Calldata, err = hex.DecodeString(l2CalldataRaw) + if err != nil { + return err + } + } + + if keyFile == "" { + return errors.New("keyfile is required") + } + + if safeAddressRaw != "" { + if !common.IsHexAddress(safeAddressRaw) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } else { + safeAddress = common.HexToAddress(safeAddressRaw) + } + + if safeApi == "" { + client, clientErr := ethclient.DialContext(context.Background(), l1Rpc) + if clientErr != nil { + return clientErr + } + + chainID, chainIDErr := client.ChainID(context.Background()) + if chainIDErr != nil { + return chainIDErr + } + safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress.Hex() + "/propose" + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if OperationType(safeOperation).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeNonceRaw != "" { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } else { + fmt.Println("--safe-nonce not specified, fetching from Safe") + } + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + fmt.Println("Bridging to", to.Hex()) + if safeAddressRaw != "" { + err := NativeTokenBridgePropose(inboxAddress, keyFile, password, l1Rpc, l2Rpc, to, l2CallValue, l2Calldata, safeAddress, safeApi, safeOperation, safeNonce) + if err != nil { + fmt.Fprintln(cmd.ErrOrStderr(), err.Error()) + return err + } + } else { + transaction, transactionErr := NativeTokenBridgeCall(inboxAddress, keyFile, password, l1Rpc, l2Rpc, to, l2CallValue, l2Calldata) + if transactionErr != nil { + fmt.Fprintln(cmd.ErrOrStderr(), transactionErr.Error()) + return transactionErr + } + + fmt.Println("Transaction sent:", transaction.Hash().Hex()) + } + + return nil + }, + } + + createCmd.Flags().StringVar(&password, "password", "", "Password to encrypt accounts with") + createCmd.Flags().StringVar(&keyFile, "keyfile", "", "Keyfile to sign transaction with") + createCmd.Flags().StringVar(&l1Rpc, "l1-rpc", "", "L1 RPC URL") + createCmd.Flags().StringVar(&l2Rpc, "l2-rpc", "", "L2 RPC URL") + createCmd.Flags().StringVar(&inboxRaw, "inbox", "", "Inbox address") + createCmd.Flags().StringVar(&toRaw, "to", "", "Recipient or contract address") + createCmd.Flags().StringVar(&l2CallValueRaw, "amount", "", "L2 call value") + createCmd.Flags().StringVar(&l2CalldataRaw, "l2-calldata", "", "Calldata to send") + createCmd.Flags().StringVar(&safeAddressRaw, "safe", "", "Address of the Safe contract") + createCmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + createCmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + createCmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce") + + return createCmd +} + +func CreateBridgeNativeTokenL1ToL3Command() *cobra.Command { + var keyFile, password, l1TokenRaw, l3FeeTokenL1AddrRaw, l1l2RouterRaw, l2l3RouterOrInboxRaw, toRaw, amountRaw, l3CalldataRaw, l1Rpc, l2Rpc, l3Rpc, teleporterAddressRaw string + teleportParams := &TeleportParams{} + var teleporterAddress common.Address + + var l3CallDataErr error + + createCmd := &cobra.Command{ + Use: "l1-to-l3", + Short: "Bridge tokens from L1 to L3", + Long: `Bridge tokens from L1 to L3 with a single transaction and arbitrary calldata`, + + PreRunE: func(cmd *cobra.Command, args []string) error { + if l3CalldataRaw != "" { + teleportParams.L3CallData, l3CallDataErr = hex.DecodeString(l3CalldataRaw) + if l3CallDataErr != nil { + return l3CallDataErr + } + } + + if !common.IsHexAddress(toRaw) { + return fmt.Errorf("invalid \"to\" address: %s", toRaw) + } + teleportParams.To = common.HexToAddress(toRaw) + + if !common.IsHexAddress(l1TokenRaw) { + return fmt.Errorf("invalid \"l1-token\" address: %s", l1TokenRaw) + } + teleportParams.L1Token = common.HexToAddress(l1TokenRaw) + + if !common.IsHexAddress(l3FeeTokenL1AddrRaw) { + return fmt.Errorf("invalid \"l3-fee-token-l1-addr\" address: %s", l3FeeTokenL1AddrRaw) + } + teleportParams.L3FeeTokenL1Addr = common.HexToAddress(l3FeeTokenL1AddrRaw) + + if !common.IsHexAddress(l1l2RouterRaw) { + return fmt.Errorf("invalid \"l1l2-router\" address: %s", l1l2RouterRaw) + } + teleportParams.L1l2Router = common.HexToAddress(l1l2RouterRaw) + + if !common.IsHexAddress(l2l3RouterOrInboxRaw) { + return fmt.Errorf("invalid \"l2l3-router-or-inbox\" address: %s", l2l3RouterOrInboxRaw) + } + teleportParams.L2l3RouterOrInbox = common.HexToAddress(l2l3RouterOrInboxRaw) + + teleportParams.Amount = new(big.Int) + if amountRaw != "" { + _, ok := teleportParams.Amount.SetString(amountRaw, 10) + if !ok { + return fmt.Errorf("invalid amount: %s", amountRaw) + } + } else { + fmt.Println("No amount provided, defaulting to 0") + teleportParams.Amount.SetInt64(0) + } + + if !common.IsHexAddress(teleporterAddressRaw) { + return fmt.Errorf("invalid teleporter address: %s", teleporterAddressRaw) + } + teleporterAddress = common.HexToAddress(teleporterAddressRaw) + + if keyFile == "" { + return errors.New("keyfile is required") + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + transaction, transactionErr := Teleport(teleporterAddress, teleportParams, keyFile, password, l1Rpc, l2Rpc, l3Rpc) + if transactionErr != nil { + fmt.Fprintln(cmd.ErrOrStderr(), transactionErr.Error()) + return transactionErr + } + + fmt.Println("Done! Transaction hash:", transaction.Hash().Hex()) + + return nil + }, + } + + createCmd.Flags().StringVar(&keyFile, "keyfile", "", "Keyfile to sign transaction with") + createCmd.Flags().StringVar(&password, "password", "", "Password to decrypt keyfile with") + createCmd.Flags().StringVar(&l1TokenRaw, "l1-token", "", "L1 token address") + createCmd.Flags().StringVar(&l3FeeTokenL1AddrRaw, "l1l3-fee-token", "", "L3 fee token L1 address") + createCmd.Flags().StringVar(&l1l2RouterRaw, "l1l2-router", "", "L1L2 router address") + createCmd.Flags().StringVar(&l2l3RouterOrInboxRaw, "l2l3-router", "", "L2L3 router or inbox address") + createCmd.Flags().StringVar(&toRaw, "to", "", "Recipient address") + createCmd.Flags().StringVar(&amountRaw, "amount", "", "Amount to send") + createCmd.Flags().StringVar(&l3CalldataRaw, "l3-calldata", "", "Calldata to send") + createCmd.Flags().StringVar(&l1Rpc, "l1-rpc", "", "L1 RPC URL") + createCmd.Flags().StringVar(&l2Rpc, "l2-rpc", "", "L2 RPC URL") + createCmd.Flags().StringVar(&l3Rpc, "l3-rpc", "", "L3 RPC URL") + createCmd.Flags().StringVar(&teleporterAddressRaw, "teleporter", "", "Teleporter contract address") + + return createCmd +} + +func CreateBridgeERC20Command() *cobra.Command { + erc20Cmd := &cobra.Command{ + Use: "erc20", + Short: "Bridge ERC20 tokens between chains", + Run: func(cmd *cobra.Command, args []string) { + cmd.Help() + }, + } + + erc20Cmd.AddCommand(CreateBridgeERC20L1ToL2Command()) + + return erc20Cmd +} + +func CreateBridgeERC20L1ToL2Command() *cobra.Command { + var keyFile, password, l1Rpc, l2Rpc, routerRaw, tokenAddressRaw, toRaw, amountRaw, safeAddressRaw, safeApi, safeNonceRaw string + var routerAddress, tokenAddress, to, safeAddress common.Address + var amount *big.Int + var safeOperation uint8 + var safeNonce *big.Int + var isCustomNativeToken bool + + createCmd := &cobra.Command{ + Use: "l1-to-l2", + Short: "Bridge ERC20 tokens from L1 to L2", + Long: `Bridge ERC20 tokens from L1 to L2 with a single transaction and arbitrary calldata`, + + PreRunE: func(cmd *cobra.Command, args []string) error { + if !common.IsHexAddress(routerRaw) { + return errors.New("invalid router address") + } + routerAddress = common.HexToAddress(routerRaw) + + if !common.IsHexAddress(toRaw) { + return errors.New("invalid recipient address") + } + to = common.HexToAddress(toRaw) + + if !common.IsHexAddress(tokenAddressRaw) { + return errors.New("invalid token address") + } + tokenAddress = common.HexToAddress(tokenAddressRaw) + + amount = new(big.Int) + if amountRaw != "" { + _, ok := amount.SetString(amountRaw, 10) + if !ok { + return errors.New("invalid L2 call value") + } + } else { + fmt.Println("No amount provided, defaulting to 0") + amount.SetInt64(0) + } + + if keyFile == "" { + return errors.New("keyfile is required") + } + + if safeAddressRaw != "" { + if !common.IsHexAddress(safeAddressRaw) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } else { + safeAddress = common.HexToAddress(safeAddressRaw) + } + + if safeApi == "" { + client, clientErr := ethclient.DialContext(context.Background(), l1Rpc) + if clientErr != nil { + return clientErr + } + + chainID, chainIDErr := client.ChainID(context.Background()) + if chainIDErr != nil { + return chainIDErr + } + safeApi = "https://safe-client.safe.global/v1/chains/" + chainID.String() + "/transactions/" + safeAddress.Hex() + "/propose" + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if OperationType(safeOperation).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeNonceRaw != "" { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } else { + fmt.Println("--safe-nonce not specified, fetching from Safe") + } + + if l1Rpc == "" { + return errors.New("l1-rpc is required") + } + + if l2Rpc == "" { + return errors.New("l2-rpc is required") + } + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + fmt.Println("Bridging", tokenAddress.Hex(), "to", to.Hex()) + if safeAddressRaw == "" { + transaction, transactionErr := ERC20BridgeCall(routerAddress, keyFile, password, l1Rpc, l2Rpc, tokenAddress, to, amount, isCustomNativeToken) + if transactionErr != nil { + fmt.Fprintln(cmd.ErrOrStderr(), transactionErr.Error()) + return transactionErr + } + fmt.Println("Transaction sent:", transaction.Hash().Hex()) + } else { + proposeErr := ERC20BridgePropose(routerAddress, keyFile, password, l1Rpc, l2Rpc, tokenAddress, to, amount, safeAddress, safeApi, safeOperation, safeNonce, isCustomNativeToken) + if proposeErr != nil { + fmt.Fprintln(cmd.ErrOrStderr(), proposeErr.Error()) + return proposeErr + } + } + + return nil + }, + } + + createCmd.Flags().StringVar(&password, "password", "", "Password to encrypt accounts with") + createCmd.Flags().StringVar(&keyFile, "keyfile", "", "Keyfile to sign transaction with") + createCmd.Flags().StringVar(&l1Rpc, "l1-rpc", "", "L1 RPC URL") + createCmd.Flags().StringVar(&l2Rpc, "l2-rpc", "", "L2 RPC URL") + createCmd.Flags().StringVar(&routerRaw, "router", "", "Router address") + createCmd.Flags().StringVar(&toRaw, "to", "", "Recipient address") + createCmd.Flags().StringVar(&tokenAddressRaw, "token", "", "Token address") + createCmd.Flags().StringVar(&amountRaw, "amount", "", "Amount to send") + createCmd.Flags().StringVar(&safeAddressRaw, "safe", "", "Address of the Safe contract") + createCmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + createCmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + createCmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce") + createCmd.Flags().BoolVar(&isCustomNativeToken, "custom-native-token", false, "Is custom native token") + + return createCmd +} diff --git a/cmd/arbitrum/aribtrum.go b/cmd/arbitrum/cmd.go similarity index 71% rename from cmd/arbitrum/aribtrum.go rename to cmd/arbitrum/cmd.go index 54e180e..11d3a21 100644 --- a/cmd/arbitrum/aribtrum.go +++ b/cmd/arbitrum/cmd.go @@ -13,6 +13,19 @@ import ( ) func CreateArbitrumCommand() *cobra.Command { + arbitrumCmd := &cobra.Command{ + Use: "arbitrum", + Short: "Bifrost for Arbitrum cross-chain messaging protocol", + Long: `Bifrost for Arbitrum cross-chain messaging protocol`, + } + + arbitrumCmd.AddCommand(CreateArbitrumMessageCommand()) + arbitrumCmd.AddCommand(CreateArbitrumBridgeCommand()) + + return arbitrumCmd +} + +func CreateArbitrumMessageCommand() *cobra.Command { var keyFile, password, l1Rpc, l2Rpc, inboxRaw, toRaw, l2CallValueRaw, l2CalldataRaw, safeAddressRaw, safeApi, safeNonceRaw string var inboxAddress, to, safeAddress common.Address var l2CallValue *big.Int @@ -20,8 +33,8 @@ func CreateArbitrumCommand() *cobra.Command { var safeOperation uint8 var safeNonce *big.Int - arbitrumCmd := &cobra.Command{ - Use: "arbitrum", + messageCmd := &cobra.Command{ + Use: "message", Short: "Bifrost for Arbitrum cross-chain messaging protocol", Long: `Bifrost for Arbitrum cross-chain messaging protocol`, @@ -119,18 +132,18 @@ func CreateArbitrumCommand() *cobra.Command { }, } - arbitrumCmd.Flags().StringVar(&password, "password", "", "Password to encrypt accounts with") - arbitrumCmd.Flags().StringVar(&keyFile, "keyfile", "", "Keyfile to sign transaction with") - arbitrumCmd.Flags().StringVar(&l1Rpc, "l1-rpc", "", "L1 RPC URL") - arbitrumCmd.Flags().StringVar(&l2Rpc, "l2-rpc", "", "L2 RPC URL") - arbitrumCmd.Flags().StringVar(&inboxRaw, "inbox", "", "Inbox address") - arbitrumCmd.Flags().StringVar(&toRaw, "to", "", "Recipient or contract address") - arbitrumCmd.Flags().StringVar(&l2CallValueRaw, "amount", "", "L2 call value") - arbitrumCmd.Flags().StringVar(&l2CalldataRaw, "l2-calldata", "", "Calldata to send") - arbitrumCmd.Flags().StringVar(&safeAddressRaw, "safe", "", "Address of the Safe contract") - arbitrumCmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") - arbitrumCmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") - arbitrumCmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce") - - return arbitrumCmd + messageCmd.Flags().StringVar(&password, "password", "", "Password to encrypt accounts with") + messageCmd.Flags().StringVar(&keyFile, "keyfile", "", "Keyfile to sign transaction with") + messageCmd.Flags().StringVar(&l1Rpc, "l1-rpc", "", "L1 RPC URL") + messageCmd.Flags().StringVar(&l2Rpc, "l2-rpc", "", "L2 RPC URL") + messageCmd.Flags().StringVar(&inboxRaw, "inbox", "", "Inbox address") + messageCmd.Flags().StringVar(&toRaw, "to", "", "Recipient or contract address") + messageCmd.Flags().StringVar(&l2CallValueRaw, "amount", "", "L2 call value") + messageCmd.Flags().StringVar(&l2CalldataRaw, "l2-calldata", "", "Calldata to send") + messageCmd.Flags().StringVar(&safeAddressRaw, "safe", "", "Address of the Safe contract") + messageCmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + messageCmd.Flags().Uint8Var(&safeOperation, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + messageCmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce") + + return messageCmd } diff --git a/cmd/arbitrum/gas.go b/cmd/arbitrum/gas.go index a168b11..99b0eb0 100644 --- a/cmd/arbitrum/gas.go +++ b/cmd/arbitrum/gas.go @@ -7,6 +7,7 @@ import ( "github.com/G7DAO/bifrost/bindings/ArbitrumL1OrbitCustomGateway" "github.com/G7DAO/bifrost/bindings/ArbitrumL1OrbitGatewayRouter" + "github.com/G7DAO/bifrost/bindings/L2ForwarderFactory" "github.com/G7DAO/bifrost/bindings/NodeInterface" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" @@ -15,6 +16,111 @@ import ( "github.com/ethereum/go-ethereum/ethclient" ) +func SetTeleporterGasParams(teleportParams *TeleportParams, teleporterAddress common.Address, l1Client *ethclient.Client, l2Client *ethclient.Client, l3Client *ethclient.Client, key *keystore.Key, teleportationType TeleportationType) (*TeleportParams, error) { + l1BaseFee, l1BaseFeeErr := l1Client.SuggestGasPrice(context.Background()) + if l1BaseFeeErr != nil { + return teleportParams, l1BaseFeeErr + } + l1BaseFee = PercentIncrease(l1BaseFee, DEFAULT_GAS_PRICE_PERCENT_INCREASE) + + l2BaseFee, l2BaseFeeErr := l2Client.SuggestGasPrice(context.Background()) + if l2BaseFeeErr != nil { + return teleportParams, l2BaseFeeErr + } + l2BaseFee = PercentIncrease(l2BaseFee, DEFAULT_GAS_PRICE_PERCENT_INCREASE) + + l3BaseFee, l3BaseFeeErr := l3Client.SuggestGasPrice(context.Background()) + if l3BaseFeeErr != nil { + return teleportParams, l3BaseFeeErr + } + l3BaseFee = PercentIncrease(l3BaseFee, DEFAULT_GAS_PRICE_PERCENT_INCREASE) + + l2FowarderAddress, l2FowarderAddressErr := GetForwarderAddress(l1Client, teleporterAddress, key, teleportParams.L2l3RouterOrInbox, teleportParams.To) + if l2FowarderAddressErr != nil { + return teleportParams, l2FowarderAddressErr + } + + // 0. Set gas prices of L2 and L3 + teleportParams.GasParams.L2GasPriceBid = l2BaseFee + teleportParams.GasParams.L3GasPriceBid = l3BaseFee + + // 1. Costs to Bridge token from L1 to L2 + l1l2TokenBridgeGasLimit, l1l2TokenBridgeMaxSubmissionCost, l1l2TokenBridgeErr := GetL1l2TokenBridgeGasParams(l1Client, l2Client, l1BaseFee, key, teleportParams, teleporterAddress, l2FowarderAddress) + if l1l2TokenBridgeErr != nil { + return teleportParams, l1l2TokenBridgeErr + } + teleportParams.GasParams.L1l2TokenBridgeMaxSubmissionCost = l1l2TokenBridgeMaxSubmissionCost + teleportParams.GasParams.L1l2TokenBridgeGasLimit = l1l2TokenBridgeGasLimit + + // 2. Costs to Forward call from L2 to L3 + l2ForwarderFactoryGasLimit, l2ForwarderFactoryMaxSubmissionCost, l2ForwarderFactoryMaxSubmissionCostErr := GetL2ForwaderGasParams(l1Client, key, teleportParams, l2FowarderAddress) + if l2ForwarderFactoryMaxSubmissionCostErr != nil { + return teleportParams, l2ForwarderFactoryMaxSubmissionCostErr + } + teleportParams.GasParams.L2ForwarderFactoryMaxSubmissionCost = l2ForwarderFactoryMaxSubmissionCost + teleportParams.GasParams.L2ForwarderFactoryGasLimit = l2ForwarderFactoryGasLimit + + // 3. Costs to bridge token from L2 to L3 + l2l3TokenBridgeGasLimit, l2l3TokenBridgeMaxSubmissionCost, l2l3TokenBridgeErr := GetL2L3TokenBridgeGasParams(l2Client, l3Client, l2BaseFee, key, teleportParams, l2FowarderAddress, teleportationType) + if l2l3TokenBridgeErr != nil { + return teleportParams, l2l3TokenBridgeErr + } + teleportParams.GasParams.L2l3TokenBridgeMaxSubmissionCost = l2l3TokenBridgeMaxSubmissionCost + teleportParams.GasParams.L2l3TokenBridgeGasLimit = l2l3TokenBridgeGasLimit + + // 4. Costs to Fee token bridge from L1 to L2 + if teleportationType == NonFeeTokenToCustomFee { + l1l2FeeTokenBridgeGasLimit, l1l2FeeTokenBridgeMaxSubmissionCost, l1l2FeeTokenBridgeErr := GetL1l2FeeTokenBridgeGasParams(l1Client, l2Client, l1BaseFee, key, teleportParams, &teleportParams.L1l2Router, teleporterAddress, l2FowarderAddress) + if l1l2FeeTokenBridgeErr != nil { + return teleportParams, l1l2FeeTokenBridgeErr + } + teleportParams.GasParams.L1l2FeeTokenBridgeMaxSubmissionCost = l1l2FeeTokenBridgeMaxSubmissionCost + teleportParams.GasParams.L1l2FeeTokenBridgeGasLimit = l1l2FeeTokenBridgeGasLimit + } else { + teleportParams.GasParams.L1l2FeeTokenBridgeMaxSubmissionCost = big.NewInt(0) + teleportParams.GasParams.L1l2FeeTokenBridgeGasLimit = uint64(0) + } + + return teleportParams, nil +} + +func GetL2ForwaderGasParams(client *ethclient.Client, key *keystore.Key, teleportParams *TeleportParams, l2ForwarderAddress common.Address) (uint64, *big.Int, error) { + baseFee, baseFeeErr := client.SuggestGasPrice(context.Background()) + if baseFeeErr != nil { + return uint64(0), nil, baseFeeErr + } + + l2ForwarderFactoryAbi, l2ForwarderFactoryAbiErr := abi.JSON(strings.NewReader(L2ForwarderFactory.L2ForwarderFactoryABI)) + if l2ForwarderFactoryAbiErr != nil { + return uint64(0), nil, l2ForwarderFactoryAbiErr + } + + l2ForwarderParams := L2ForwarderParams{ + Owner: key.Address, + L2Token: teleportParams.L1Token, + L3FeeTokenL2Addr: teleportParams.L3FeeTokenL1Addr, + RouterOrInbox: teleportParams.L2l3RouterOrInbox, + To: teleportParams.To, + GasLimit: big.NewInt(0), + GasPriceBid: big.NewInt(0), + MaxSubmissionCost: big.NewInt(0), + L3CallData: teleportParams.L3CallData, + } + + l2ForwarderCalldata, l2ForwarderCalldataErr := l2ForwarderFactoryAbi.Pack("callForwarder", l2ForwarderParams) + if l2ForwarderCalldataErr != nil { + return uint64(0), nil, l2ForwarderCalldataErr + } + + l2ForwarderFactoryMaxSubmissionCost, l2ForwarderFactoryMaxSubmissionCostErr := CalculateRetryableSubmissionFee(l2ForwarderCalldata, baseFee) + if l2ForwarderFactoryMaxSubmissionCostErr != nil { + return uint64(0), nil, l2ForwarderFactoryMaxSubmissionCostErr + } + l2ForwarderFactoryGasLimit := PercentIncrease(big.NewInt(int64(L2_FORWARDER_FACTORY_DEFAULT_GAS_LIMIT)), DEFAULT_GAS_LIMIT_PERCENT_INCREASE).Uint64() + + return l2ForwarderFactoryGasLimit, l2ForwarderFactoryMaxSubmissionCost, nil +} + func GetL1l2TokenBridgeGasParams(l1Client *ethclient.Client, l2Client *ethclient.Client, l1BaseFee *big.Int, key *keystore.Key, teleportParams *TeleportParams, teleporterAddress common.Address, l2ForwarderAddress common.Address) (uint64, *big.Int, error) { router, routerErr := ArbitrumL1OrbitGatewayRouter.NewL1OrbitGatewayRouter(teleportParams.L1l2Router, l1Client) if routerErr != nil { @@ -56,6 +162,48 @@ func GetL1l2TokenBridgeGasParams(l1Client *ethclient.Client, l2Client *ethclient return l1l2TokenBridgeGasLimit, l1l2TokenBridgeMaxSubmissionCost, nil } +func GetL2L3TokenBridgeGasParams(l2Client *ethclient.Client, l3Client *ethclient.Client, l2BaseFee *big.Int, key *keystore.Key, teleportParams *TeleportParams, l2ForwarderAddress common.Address, teleportationType TeleportationType) (uint64, *big.Int, error) { + outboundCalldata := teleportParams.L3CallData + var outboundCalldataErr error + + if teleportationType == NonFeeTokenToCustomFee { + router, routerErr := ArbitrumL1OrbitGatewayRouter.NewL1OrbitGatewayRouter(teleportParams.L1l2Router, l2Client) + if routerErr != nil { + return uint64(0), nil, routerErr + } + + gatewayAddress, gatewayAddressErr := router.GetGateway(nil, teleportParams.L1Token) + if gatewayAddressErr != nil { + return uint64(0), nil, gatewayAddressErr + } + + gateway, gatewayErr := ArbitrumL1OrbitCustomGateway.NewL1OrbitCustomGateway(gatewayAddress, l2Client) + if gatewayErr != nil { + return uint64(0), nil, gatewayErr + } + + outboundCalldata, outboundCalldataErr = gateway.GetOutboundCalldata(nil, teleportParams.L1Token, teleportParams.To, l2ForwarderAddress, teleportParams.Amount, teleportParams.L3CallData) + if outboundCalldataErr != nil { + return uint64(0), nil, outboundCalldataErr + } + } + + l2l3TokenBridgeMaxSubmissionCost, l2l3TokenBridgeMaxSubmissionCostErr := CalculateRetryableSubmissionFee(outboundCalldata, l2BaseFee) + if l2l3TokenBridgeMaxSubmissionCostErr != nil { + return uint64(0), nil, l2l3TokenBridgeMaxSubmissionCostErr + } + + // Source: https://github.com/OffchainLabs/arbitrum-sdk/blob/0da65020438fc3e46728ea182f1b4dcf04e3cb7f/src/lib/message/L1ToL2MessageGasEstimator.ts#L154-L155 + senderDeposit := big.NewInt(0).Add(teleportParams.Amount, ONE_ETHER) + + l2l3TokenBridgeGasLimit, l2l3TokenBridgeGasLimitErr := CalculateRetryableGasLimit(l3Client, l2ForwarderAddress, senderDeposit, teleportParams.To, teleportParams.Amount, teleportParams.To, teleportParams.To, teleportParams.L3CallData) + if l2l3TokenBridgeGasLimitErr != nil { + return uint64(0), nil, l2l3TokenBridgeGasLimitErr + } + + return l2l3TokenBridgeGasLimit, l2l3TokenBridgeMaxSubmissionCost, nil +} + func GetL1l2FeeTokenBridgeGasParams(l1Client *ethclient.Client, l2Client *ethclient.Client, l1BaseFee *big.Int, key *keystore.Key, teleportParams *TeleportParams, l1l2RouterAddress *common.Address, teleporterAddress common.Address, l2ForwarderAddress common.Address) (uint64, *big.Int, error) { router, routerErr := ArbitrumL1OrbitGatewayRouter.NewL1OrbitGatewayRouter(teleportParams.L1l2Router, l1Client) if routerErr != nil { diff --git a/cmd/arbitrum/helpers.go b/cmd/arbitrum/helpers.go index 3c9ffd1..1a00dd9 100644 --- a/cmd/arbitrum/helpers.go +++ b/cmd/arbitrum/helpers.go @@ -1,11 +1,34 @@ package arbitrum_bifrost import ( + "fmt" "math/big" + "github.com/G7DAO/bifrost/bindings/L1Teleporter" + "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" ) +func GetForwarderAddress(client *ethclient.Client, teleporterAddress common.Address, key *keystore.Key, l2l3RouterOrInbox common.Address, to common.Address) (common.Address, error) { + teleporter, teleporterErr := L1Teleporter.NewL1Teleporter(teleporterAddress, client) + if teleporterErr != nil { + return common.Address{}, teleporterErr + } + + l2ForwarderAddress, l2ForwarderAddressErr := teleporter.L2ForwarderAddress( + nil, + key.Address, + l2l3RouterOrInbox, + to, + ) + if l2ForwarderAddressErr != nil { + return common.Address{}, l2ForwarderAddressErr + } + + return l2ForwarderAddress, nil +} + // Source: https://github.com/OffchainLabs/nitro-contracts/blob/main/src/bridge/Inbox.sol#L323 func CalculateRetryableSubmissionFee(calldata []byte, baseFee *big.Int) (*big.Int, error) { multiplier := big.NewInt(int64(1400 + 6*len(calldata))) @@ -50,6 +73,19 @@ func CalculateRequiredEth(gasParams RetryableGasParams, teleportationType Telepo return requiredEth, requiredFeeToken } +// Source: https://github.com/OffchainLabs/l1-l3-teleport-contracts/blob/820590ff81f85ca482c9d9aec6948c1277248950/contracts/lib/TeleportationType.sol#L13 +func GetTeleportationType(token common.Address, feeToken common.Address) (TeleportationType, error) { + if (token == common.Address{}) { + return Standard, fmt.Errorf("token address is empty") + } else if (feeToken == common.Address{}) { + return Standard, nil + } else if token == feeToken { + return OnlyCustomFee, nil + } else { + return NonFeeTokenToCustomFee, nil + } +} + // Source: https://github.com/OffchainLabs/nitro/blob/057bf836fcf719e803b0486914bc957134f691fd/arbos/util/util.go#L204 func RemapL1Address(l1Addr common.Address) common.Address { AddressAliasOffset, success := new(big.Int).SetString("0x1111000000000000000000000000000000001111", 0) diff --git a/cmd/arbitrum/teleporter.go b/cmd/arbitrum/teleporter.go new file mode 100644 index 0000000..5651b7a --- /dev/null +++ b/cmd/arbitrum/teleporter.go @@ -0,0 +1,74 @@ +package arbitrum_bifrost + +import ( + "context" + "fmt" + "os" + "strings" + + "github.com/G7DAO/bifrost/bindings/L1Teleporter" + "github.com/G7DAO/bifrost/bindings/NodeInterface" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" +) + +func Teleport(teleporter common.Address, teleportParams *TeleportParams, keyFile string, password string, l1Rpc string, l2Rpc string, l3Rpc string) (*types.Transaction, error) { + l1Client, l1ClientErr := ethclient.DialContext(context.Background(), l1Rpc) + if l1ClientErr != nil { + return nil, l1ClientErr + } + + l2Client, l2ClientErr := ethclient.DialContext(context.Background(), l2Rpc) + if l2ClientErr != nil { + return nil, l2ClientErr + } + + l3Client, l3ClientErr := ethclient.DialContext(context.Background(), l3Rpc) + if l3ClientErr != nil { + return nil, l3ClientErr + } + + key, keyErr := NodeInterface.KeyFromFile(keyFile, password) + if keyErr != nil { + return nil, keyErr + } + + teleportationType, teleportationTypeErr := GetTeleportationType(teleportParams.L1Token, teleportParams.L3FeeTokenL1Addr) + if teleportationTypeErr != nil { + return nil, teleportationTypeErr + } + + teleportParams, teleportParamsErr := SetTeleporterGasParams(teleportParams, teleporter, l1Client, l2Client, l3Client, key, teleportationType) + if teleportParamsErr != nil { + return nil, teleportParamsErr + } + + requiredEth, requiredFeeToken := CalculateRequiredEth(teleportParams.GasParams, teleportationType) + if teleportationType == OnlyCustomFee && teleportParams.Amount.Cmp(requiredFeeToken) == -1 { + fmt.Fprintln(os.Stderr, "Amount is less than required fee token amount") + return nil, nil + } + + teleportParams.Amount.Add(teleportParams.Amount, requiredFeeToken) + + teleporterAbi, teleporterAbiErr := abi.JSON(strings.NewReader(L1Teleporter.L1TeleporterABI)) + if teleporterAbiErr != nil { + return nil, teleporterAbiErr + } + + data, dataErr := teleporterAbi.Pack("teleport", teleportParams) + if dataErr != nil { + fmt.Fprintln(os.Stderr, dataErr.Error()) + return nil, dataErr + } + + transaction, transactionErr := SendTransaction(l1Client, key, password, data, teleporter.String(), requiredEth) + if transactionErr != nil { + fmt.Fprintln(os.Stderr, transactionErr.Error()) + return nil, transactionErr + } + + return transaction, nil +}