diff --git a/.gitignore b/.gitignore index ee3f7bfc1..5e3ed4039 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ UniversalTeleporterMessengerContractAddress.txt # miscellaneous .idea/ +contracts/pkg # Generated template files docker-compose-test-local.yml diff --git a/abi-bindings/go/CrossChainApplications/ERC20Bridge/ERC20Bridge/ERC20Bridge.go b/abi-bindings/go/CrossChainApplications/ERC20Bridge/ERC20Bridge/ERC20Bridge.go index 0b540aa4b..c810572b5 100644 --- a/abi-bindings/go/CrossChainApplications/ERC20Bridge/ERC20Bridge/ERC20Bridge.go +++ b/abi-bindings/go/CrossChainApplications/ERC20Bridge/ERC20Bridge/ERC20Bridge.go @@ -32,7 +32,7 @@ var ( // ERC20BridgeMetaData contains all meta data concerning the ERC20Bridge contract. var ERC20BridgeMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenContractAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"teleporterMessageID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destinationBridgeAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"BridgeTokens\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"nativeBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nativeBridgeAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nativeContractAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"bridgeTokenAddress\",\"type\":\"address\"}],\"name\":\"CreateBridgeToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"MintBridgeTokens\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"destinationBridgeAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nativeContractAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"teleporterMessageID\",\"type\":\"uint256\"}],\"name\":\"SubmitCreateBridgeToken\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"CREATE_BRIDGE_TOKENS_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINT_BRIDGE_TOKENS_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TRANSFER_BRIDGE_TOKENS_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"WARP_PRECOMPILE_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationBridgeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenContractAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"totalAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"primaryFeeAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"secondaryFeeAmount\",\"type\":\"uint256\"}],\"name\":\"bridgeTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationBridgeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nativeTokenContract\",\"type\":\"address\"}],\"name\":\"bridgedBalances\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nativeContractAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"nativeName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"nativeSymbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"nativeDecimals\",\"type\":\"uint8\"}],\"name\":\"encodeCreateBridgeTokenData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nativeContractAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"bridgeAmount\",\"type\":\"uint256\"}],\"name\":\"encodeMintBridgeTokensData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationBridgeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nativeContractAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"}],\"name\":\"encodeTransferBridgeTokensData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nativeBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"nativeBridgeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nativeTokenAddress\",\"type\":\"address\"}],\"name\":\"nativeToWrappedTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"bridgeTokenAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"nativeBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"nativeBridgeAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationBridgeAddress\",\"type\":\"address\"},{\"internalType\":\"contractERC20\",\"name\":\"nativeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageFeeAsset\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"messageFeeAmount\",\"type\":\"uint256\"}],\"name\":\"submitCreateBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationBridgeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nativeTokenContract\",\"type\":\"address\"}],\"name\":\"submittedBridgeTokenCreations\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"tokenCreationSubmitted\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"teleporterRegistry\",\"outputs\":[{\"internalType\":\"contractTeleporterRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"wrappedTokenContracts\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"bridgeTokenExists\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60c06040523480156200001157600080fd5b506040516200408c3803806200408c833981016040819052620000349162000212565b600160005580806001600160a01b038116620000bc5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f727465725570677261646561626c653a207a65726f2074656c6560448201527f706f727465722072656769737472792061646472657373000000000000000000606482015260840160405180910390fd5b6001600160a01b03811660808190526040805163301fd1f560e21b8152905163c07f47d4916004808201926020929091908290030181865afa15801562000107573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200012d919062000244565b600155506200013c33620001c0565b507302000000000000000000000000000000000000056001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000190573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b6919062000244565b60a052506200025e565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602082840312156200022557600080fd5b81516001600160a01b03811681146200023d57600080fd5b9392505050565b6000602082840312156200025757600080fd5b5051919050565b60805160a051613dd0620002bc600039600081816101c7015281816109cb015281816117ba0152611e8001526000818161015c015281816104620152818161087d01528181610c8b015281816112d901526117fe0152613dd06000f3fe60806040523480156200001157600080fd5b5060043610620001515760003560e01c80638343f66111620000c7578063b9e55da11162000086578063b9e55da11462000329578063c60da612146200035d578063c63d22071462000374578063c868efaa146200038b578063e49cc55314620003a2578063f2fde38b14620003ac57600080fd5b80638343f66114620002885780638c56fcf014620002d05780638da5cb5b14620002e75780639bd9abc014620002f9578063b6109d9d146200031f57600080fd5b80636b47cd9a11620001145780636b47cd9a14620002405780636c7e40d1146200024b578063715018a6146200026457806374971856146200026e5780637a465fd9146200027d57600080fd5b80631a7f5bec1462000156578063367e9584146200019b5780634950d2d014620001c15780635f217bcc14620001f8578063654355681462000203575b600080fd5b6200017e7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b620001b2620001ac36600462002292565b620003c3565b6040516200019291906200237a565b620001e97f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200162000192565b620001e9621e848081565b6200017e620002143660046200238f565b60066020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b620001e9620493e081565b620002626200025c366004620023d6565b62000422565b005b62000262620007f7565b6200017e6005600160991b0181565b620001e962030d4081565b620002bf620002993660046200238f565b600360209081526000938452604080852082529284528284209052825290205460ff1681565b604051901515815260200162000192565b620001b2620002e136600462002438565b6200080f565b6002546001600160a01b03166200017e565b620002bf6200030a3660046200247e565b60056020526000908152604090205460ff1681565b620002626200086a565b620001e96200033a3660046200238f565b600460209081526000938452604080852082529284528284209052825290205481565b620001b26200036e3660046200249e565b6200093f565b62000262620003853660046200250a565b620009bf565b620002626200039c3660046200257f565b62000c73565b620001e960015481565b62000262620003bd3660046200247e565b62000ee8565b6060600085858585604051602001620003e094939291906200260f565b60405160208183030381529060405290506000816040516020016200040792919062002674565b6040516020818303038152906040529150505b949350505050565b6200042c62000f64565b6001600160a01b0384166200045e5760405162461bcd60e51b81526004016200045590620026ae565b60405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d820e64f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620004bf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004e59190620026fa565b9050600082156200051457620004fc848462000fbf565b9050620005146001600160a01b038516838362001135565b60006200065286876001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156200055a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000584919081019062002766565b886001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620005c3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620005ed919081019062002766565b896001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200062c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ac91906200279f565b90506000836001600160a01b031663624488506040518060c001604052808c81526020018b6001600160a01b0316815260200160405180604001604052808b6001600160a01b03168152602001888152508152602001621e84808152602001600067ffffffffffffffff811115620006ce57620006ce620021a0565b604051908082528060200260200182016040528015620006f8578160200160208202803683370190505b508152602001858152506040518263ffffffff1660e01b815260040162000720919062002805565b6020604051808303816000875af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000766919062002887565b60008a81526003602090815260408083206001600160a01b03808e16808652918452828520908d16808652935292819020805460ff1916600117905551929350918b907f110b902745a3d7d6b66732479f01de654a3bc6e501be7c8ba2c3a6f9868cb53990620007d99086815260200190565b60405180910390a450505050620007f06001600055565b5050505050565b6200080162001227565b6200080d600062001283565b565b606060008484846040516020016200082a93929190620028a1565b60405160208183030381529060405290506001816040516020016200085192919062002674565b6040516020818303038152906040529150509392505050565b6200087462001227565b600060015490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015620008da573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000900919062002887565b60018190558110156200093c5760015460405182907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d90600090a35b50565b60408051602081018890526001600160a01b0387811682840152868116606080840191909152908616608083015260a0820185905260c08083018590528351808403909101815260e083019093529190620009a39060029083906101000162002674565b6040516020818303038152906040529150509695505050505050565b620009c962000f64565b7f0000000000000000000000000000000000000000000000000000000000000000870362000a0b5760405162461bcd60e51b81526004016200045590620028c5565b6001600160a01b03841662000a345760405162461bcd60e51b815260040162000455906200290d565b6001600160a01b03861662000a5d5760405162461bcd60e51b81526004016200045590620026ae565b6001600160a01b03851660009081526005602052604090205460ff161562000b485762000a8b818362002966565b831162000aea5760405162461bcd60e51b815260206004820152602660248201527f45524332304272696467653a20696e73756666696369656e7420746f74616c20604482015265185b5bdd5b9d60d21b606482015260840162000455565b62000b426040518060e00160405280898152602001886001600160a01b03168152602001876001600160a01b03168152602001866001600160a01b0316815260200185815260200184815260200183815250620012d5565b62000c5f565b60008781526003602090815260408083206001600160a01b03808b168552908352818420908916845290915290205460ff1662000bda5760405162461bcd60e51b815260206004820152602960248201527f45524332304272696467653a20696e76616c69642062726964676520746f6b656044820152686e206164647265737360b81b606482015260840162000455565b600062000be8868562000fbf565b905082811162000c4d5760405162461bcd60e51b815260206004820152602960248201527f45524332304272696467653a20696e73756666696369656e742061646a757374604482015268195908185b5bdd5b9d60ba1b606482015260840162000455565b62000c5d8888888885886200173c565b505b62000c6a6001600055565b50505050505050565b60015460405163260f846760e11b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634c1f08ce90602401602060405180830381865afa15801562000cdb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d01919062002887565b101562000d6a5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f727465725570677261646561626c653a20696e76616c6964207460448201526f32b632b837b93a32b91039b2b73232b960811b606482015260840162000455565b60008062000d7b838501856200297c565b9092509050600082600281111562000d975762000d976200265e565b0362000ddb576000806000808480602001905181019062000db99190620029ea565b935093509350935062000dd18a8a8686868662001a73565b5050505062000ee0565b600182600281111562000df25762000df26200265e565b0362000e315760008060008380602001905181019062000e13919062002a74565b92509250925062000e28898985858562001be2565b50505062000ee0565b600282600281111562000e485762000e486200265e565b0362000e97576000806000806000808680602001905181019062000e6d919062002abc565b95509550955095509550955062000e8b8c8c88888888888862001d5c565b50505050505062000ee0565b60405162461bcd60e51b815260206004820152601b60248201527f45524332304272696467653a20696e76616c696420616374696f6e0000000000604482015260640162000455565b505050505050565b62000ef262001227565b6001600160a01b03811662000f595760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000455565b6200093c8162001283565b60026000540362000fb85760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162000455565b6002600055565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa15801562001009573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200102f919062002887565b9050620010486001600160a01b03851633308662001f15565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa15801562001090573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620010b6919062002887565b90508181116200111e5760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b606482015260840162000455565b6200112a828262002b2c565b925050505b92915050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562001187573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620011ad919062002887565b620011b9919062002966565b6040516001600160a01b0385166024820152604481018290529091506200122190859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915262001f39565b50505050565b6002546001600160a01b031633146200080d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000455565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d820e64f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001336573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200135c9190620026fa565b90506000808360a0015111156200139f576200138183604001518460a0015162000fbf565b60408401519091506200139f906001600160a01b0316838362001135565b60008360a001518460800151620013b7919062002b2c565b604085810151905163079cc67960e41b815233600482015260248101839052919250906001600160a01b038216906379cc679090604401600060405180830381600087803b1580156200140957600080fd5b505af11580156200141e573d6000803e3d6000fd5b505050506000816001600160a01b031663f72539686040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001463573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001489919062002887565b90506000826001600160a01b0316631a0b79bf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620014cc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620014f29190620026fa565b9050818760000151036200153857806001600160a01b031687602001516001600160a01b031614620015385760405162461bcd60e51b8152600401620004559062002b42565b6000620015be88600001518960200151866001600160a01b03166374d32ad46040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001587573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620015ad9190620026fa565b8b60600151898d60c001516200093f565b90506000876001600160a01b031663624488506040518060c00160405280878152602001866001600160a01b0316815260200160405180604001604052808e604001516001600160a01b031681526020018c8152508152602001620493e08152602001600067ffffffffffffffff8111156200163e576200163e620021a0565b60405190808252806020026020018201604052801562001668578160200160208202803683370190505b508152602001858152506040518263ffffffff1660e01b815260040162001690919062002805565b6020604051808303816000875af1158015620016b0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620016d6919062002887565b90508089600001518a604001516001600160a01b03167f97935c4470efae40c8440c3abfe968a5512232dd375cc974e712f487c2b99c318c602001518d606001518b6040516200172993929190620028a1565b60405180910390a4505050505050505050565b6001600160a01b03841660009081526005602052604090205460ff1615620017b85760405162461bcd60e51b815260206004820152602860248201527f45524332304272696467653a2063616e6e6f742062726964676520777261707060448201526732b2103a37b5b2b760c11b606482015260840162000455565b7f00000000000000000000000000000000000000000000000000000000000000008603620017fa5760405162461bcd60e51b81526004016200045590620028c5565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d820e64f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200185b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018819190620026fa565b90508115620018a057620018a06001600160a01b038616828462001135565b6000620018ae838562002b2c565b60008981526004602090815260408083206001600160a01b03808d168552908352818420908b168452909152812080549293508392909190620018f390849062002966565b9091555060009050620019088787846200080f565b90506000836001600160a01b031663624488506040518060c001604052808d81526020018c6001600160a01b0316815260200160405180604001604052808d6001600160a01b031681526020018a815250815260200162030d408152602001600067ffffffffffffffff811115620019845762001984620021a0565b604051908082528060200260200182016040528015620019ae578160200160208202803683370190505b508152602001858152506040518263ffffffff1660e01b8152600401620019d6919062002805565b6020604051808303816000875af1158015620019f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a1c919062002887565b9050808a896001600160a01b03167f97935c4470efae40c8440c3abfe968a5512232dd375cc974e712f487c2b99c318c8b8860405162001a5f93929190620028a1565b60405180910390a450505050505050505050565b60008681526006602090815260408083206001600160a01b038981168552908352818420888216855290925290912054161562001b045760405162461bcd60e51b815260206004820152602860248201527f45524332304272696467653a2062726964676520746f6b656e20616c72656164604482015267792065786973747360c01b606482015260840162000455565b600086868686868660405162001b1a906200217c565b62001b2b9695949392919062002b91565b604051809103906000f08015801562001b48573d6000803e3d6000fd5b506001600160a01b038181166000818152600560209081526040808320805460ff191660011790558c8352600682528083208c8616808552908352818420958c168085529583529281902080546001600160a01b031916851790555192835293945091928a917fe1c61a845f79534e11924517ddbedc668d0c20e467eafb4d3bd2858e2815f3b5910160405180910390a450505050505050565b62001bec62000f64565b6001600160a01b03821662001c155760405162461bcd60e51b815260040162000455906200290d565b60008581526006602090815260408083206001600160a01b038089168552908352818420878216855290925290912054168062001ca65760405162461bcd60e51b815260206004820152602860248201527f45524332304272696467653a2062726964676520746f6b656e20646f6573206e6044820152671bdd08195e1a5cdd60c21b606482015260840162000455565b6040516340c10f1960e01b81526001600160a01b038481166004830152602482018490528216906340c10f1990604401600060405180830381600087803b15801562001cf157600080fd5b505af115801562001d06573d6000803e3d6000fd5b5050604080516001600160a01b03878116825260208201879052851693507fc0767f158f0d5394b598489a51ed607cd55a8be2dcef113ba1626efcf4c6395492500160405180910390a250620007f06001600055565b62001d6662000f64565b6001600160a01b03831662001d8f5760405162461bcd60e51b815260040162000455906200290d565b6001600160a01b03851662001db85760405162461bcd60e51b81526004016200045590620026ae565b60008881526004602090815260408083206001600160a01b03808c16855290835281842090881684529091529020548281101562001e435760405162461bcd60e51b815260206004820152602160248201527f45524332304272696467653a20696e73756666696369656e742062616c616e636044820152606560f81b606482015260840162000455565b62001e4f838262002b2c565b60008a81526004602090815260408083206001600160a01b03808e168552908352818420908a1684529091529020557f0000000000000000000000000000000000000000000000000000000000000000870362001eee576001600160a01b038616301462001ed15760405162461bcd60e51b8152600401620004559062002b42565b62001ee76001600160a01b038616858562002017565b5062001f00565b62001efe8787878787876200173c565b505b62001f0b6001600055565b5050505050505050565b62001221846323b872dd60e01b858585604051602401620011e993929190620028a1565b600062001f90826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620020499092919063ffffffff16565b80519091501562002012578080602001905181019062001fb1919062002bf0565b620020125760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000455565b505050565b6040516001600160a01b0383166024820152604481018290526200201290849063a9059cbb60e01b90606401620011e9565b60606200041a848460008585600080866001600160a01b0316858760405162002073919062002c14565b60006040518083038185875af1925050503d8060008114620020b2576040519150601f19603f3d011682016040523d82523d6000602084013e620020b7565b606091505b5091509150620020ca87838387620020d5565b979650505050505050565b606083156200214957825160000362002141576001600160a01b0385163b620021415760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000455565b50816200041a565b6200041a8383815115620021605781518083602001fd5b8060405162461bcd60e51b81526004016200045591906200237a565b6111688062002c3383390190565b6001600160a01b03811681146200093c57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715620021e257620021e2620021a0565b604052919050565b600067ffffffffffffffff821115620022075762002207620021a0565b50601f01601f191660200190565b60006200222c6200222684620021ea565b620021b6565b90508281528383830111156200224157600080fd5b828260208301376000602084830101529392505050565b600082601f8301126200226a57600080fd5b6200227b8383356020850162002215565b9392505050565b60ff811681146200093c57600080fd5b60008060008060808587031215620022a957600080fd5b8435620022b6816200218a565b9350602085013567ffffffffffffffff80821115620022d457600080fd5b620022e28883890162002258565b94506040870135915080821115620022f957600080fd5b50620023088782880162002258565b92505060608501356200231b8162002282565b939692955090935050565b60005b838110156200234357818101518382015260200162002329565b50506000910152565b600081518084526200236681602086016020860162002326565b601f01601f19169290920160200192915050565b6020815260006200227b60208301846200234c565b600080600060608486031215620023a557600080fd5b833592506020840135620023b9816200218a565b91506040840135620023cb816200218a565b809150509250925092565b600080600080600060a08688031215620023ef57600080fd5b85359450602086013562002403816200218a565b9350604086013562002415816200218a565b9250606086013562002427816200218a565b949793965091946080013592915050565b6000806000606084860312156200244e57600080fd5b83356200245b816200218a565b925060208401356200246d816200218a565b929592945050506040919091013590565b6000602082840312156200249157600080fd5b81356200227b816200218a565b60008060008060008060c08789031215620024b857600080fd5b863595506020870135620024cc816200218a565b94506040870135620024de816200218a565b93506060870135620024f0816200218a565b9598949750929560808101359460a0909101359350915050565b600080600080600080600060e0888a0312156200252657600080fd5b8735965060208801356200253a816200218a565b955060408801356200254c816200218a565b945060608801356200255e816200218a565b9699959850939660808101359560a0820135955060c0909101359350915050565b600080600080606085870312156200259657600080fd5b843593506020850135620025aa816200218a565b9250604085013567ffffffffffffffff80821115620025c857600080fd5b818701915087601f830112620025dd57600080fd5b813581811115620025ed57600080fd5b8860208285010111156200260057600080fd5b95989497505060200194505050565b6001600160a01b038516815260806020820181905260009062002635908301866200234c565b82810360408401526200264981866200234c565b91505060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b6000600384106200269557634e487b7160e01b600052602160045260246000fd5b838252604060208301526200041a60408301846200234c565b6020808252602c908201527f45524332304272696467653a207a65726f2064657374696e6174696f6e20627260408201526b69646765206164647265737360a01b606082015260800190565b6000602082840312156200270d57600080fd5b81516200227b816200218a565b600082601f8301126200272c57600080fd5b81516200273d6200222682620021ea565b8181528460208386010111156200275357600080fd5b6200041a82602083016020870162002326565b6000602082840312156200277957600080fd5b815167ffffffffffffffff8111156200279157600080fd5b6200041a848285016200271a565b600060208284031215620027b257600080fd5b81516200227b8162002282565b600081518084526020808501945080840160005b83811015620027fa5781516001600160a01b031687529582019590820190600101620027d3565b509495945050505050565b60208152815160208201526000602083015160018060a01b03808216604085015260408501519150808251166060850152506020810151608084015250606083015160a0830152608083015160e060c084015262002868610100840182620027bf565b905060a0840151601f198483030160e08501526200112a82826200234c565b6000602082840312156200289a57600080fd5b5051919050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60208082526028908201527f45524332304272696467653a2063616e6e6f742062726964676520746f20736160408201526736b29031b430b4b760c11b606082015260800190565b60208082526023908201527f45524332304272696467653a207a65726f20726563697069656e74206164647260408201526265737360e81b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b808201808211156200112f576200112f62002950565b600080604083850312156200299057600080fd5b823560038110620029a057600080fd5b9150602083013567ffffffffffffffff811115620029bd57600080fd5b8301601f81018513620029cf57600080fd5b620029e08582356020840162002215565b9150509250929050565b6000806000806080858703121562002a0157600080fd5b845162002a0e816200218a565b602086015190945067ffffffffffffffff8082111562002a2d57600080fd5b62002a3b888389016200271a565b9450604087015191508082111562002a5257600080fd5b5062002a61878288016200271a565b92505060608501516200231b8162002282565b60008060006060848603121562002a8a57600080fd5b835162002a97816200218a565b602085015190935062002aaa816200218a565b80925050604084015190509250925092565b60008060008060008060c0878903121562002ad657600080fd5b86519550602087015162002aea816200218a565b604088015190955062002afd816200218a565b606088015190945062002b10816200218a565b809350506080870151915060a087015190509295509295509295565b818103818111156200112f576200112f62002950565b6020808252602f908201527f45524332304272696467653a20696e76616c69642064657374696e6174696f6e60408201526e20627269646765206164647265737360881b606082015260800190565b8681526001600160a01b0386811660208301528516604082015260c06060820181905260009062002bc5908301866200234c565b828103608084015262002bd981866200234c565b91505060ff831660a0830152979650505050505050565b60006020828403121562002c0357600080fd5b815180151581146200227b57600080fd5b6000825162002c2881846020870162002326565b919091019291505056fe6101206040523480156200001257600080fd5b506040516200116838038062001168833981016040819052620000359162000292565b82826003620000458382620003d5565b506004620000548282620003d5565b50879150620000b690505760405162461bcd60e51b815260206004820152602160248201527f427269646765546f6b656e3a207a65726f20736f7572636520636861696e20696044820152601960fa1b60648201526084015b60405180910390fd5b6001600160a01b0385166200011e5760405162461bcd60e51b815260206004820152602760248201527f427269646765546f6b656e3a207a65726f20736f7572636520627269646765206044820152666164647265737360c81b6064820152608401620000ad565b6001600160a01b038416620001855760405162461bcd60e51b815260206004820152602660248201527f427269646765546f6b656e3a207a65726f20736f75726365206173736574206160448201526564647265737360d01b6064820152608401620000ad565b3360805260a09590955250506001600160a01b0391821660c0521660e05260ff1661010052620004a1565b80516001600160a01b0381168114620001c857600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f557600080fd5b81516001600160401b0380821115620002125762000212620001cd565b604051601f8301601f19908116603f011681019082821181831017156200023d576200023d620001cd565b816040528381526020925086838588010111156200025a57600080fd5b600091505b838210156200027e57858201830151818301840152908201906200025f565b600093810190920192909252949350505050565b60008060008060008060c08789031215620002ac57600080fd5b86519550620002be60208801620001b0565b9450620002ce60408801620001b0565b60608801519094506001600160401b0380821115620002ec57600080fd5b620002fa8a838b01620001e3565b945060808901519150808211156200031157600080fd5b506200032089828a01620001e3565b92505060a087015160ff811681146200033857600080fd5b809150509295509295509295565b600181811c908216806200035b57607f821691505b6020821081036200037c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003d057600081815260208120601f850160051c81016020861015620003ab5750805b601f850160051c820191505b81811015620003cc57828155600101620003b7565b5050505b505050565b81516001600160401b03811115620003f157620003f1620001cd565b620004098162000402845462000346565b8462000382565b602080601f831160018114620004415760008415620004285750858301515b600019600386901b1c1916600185901b178555620003cc565b600085815260208120601f198616915b82811015620004725788860151825594840194600190910190840162000451565b5085821015620004915787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610c7b620004ed60003960006101c70152600061025a01526000610173015260006102fc0152600081816102c2015261041b0152610c7b6000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610297578063a9059cbb146102aa578063cd596583146102bd578063dd62ed3e146102e4578063f7253968146102f757600080fd5b806370a082311461022c57806374d32ad41461025557806379cc67901461027c57806395d89b411461028f57600080fd5b806323b872dd116100e957806323b872dd146101ad578063313ce567146101c057806339509351146101f157806340c10f191461020457806342966c681461021957600080fd5b806306fdde031461011b578063095ea7b31461013957806318160ddd1461015c5780631a0b79bf1461016e575b600080fd5b61012361031e565b6040516101309190610aac565b60405180910390f35b61014c610147366004610b16565b6103b0565b6040519015158152602001610130565b6002545b604051908152602001610130565b6101957f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610130565b61014c6101bb366004610b40565b6103ca565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610130565b61014c6101ff366004610b16565b6103ee565b610217610212366004610b16565b610410565b005b610217610227366004610b7c565b61049b565b61016061023a366004610b95565b6001600160a01b031660009081526020819052604090205490565b6101957f000000000000000000000000000000000000000000000000000000000000000081565b61021761028a366004610b16565b6104a8565b6101236104bd565b61014c6102a5366004610b16565b6104cc565b61014c6102b8366004610b16565b610547565b6101957f000000000000000000000000000000000000000000000000000000000000000081565b6101606102f2366004610bb7565b610555565b6101607f000000000000000000000000000000000000000000000000000000000000000081565b60606003805461032d90610bea565b80601f016020809104026020016040519081016040528092919081815260200182805461035990610bea565b80156103a65780601f1061037b576101008083540402835291602001916103a6565b820191906000526020600020905b81548152906001019060200180831161038957829003601f168201915b5050505050905090565b6000336103be818585610580565b60019150505b92915050565b6000336103d88582856106a5565b6103e385858561071f565b506001949350505050565b6000336103be8185856104018383610555565b61040b9190610c24565b610580565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461048d5760405162461bcd60e51b815260206004820152601960248201527f427269646765546f6b656e3a20756e617574686f72697a65640000000000000060448201526064015b60405180910390fd5b61049782826108c3565b5050565b6104a53382610982565b50565b6104b38233836106a5565b6104978282610982565b60606004805461032d90610bea565b600033816104da8286610555565b90508381101561053a5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610484565b6103e38286868403610580565b6000336103be81858561071f565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b0383166105e25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610484565b6001600160a01b0382166106435760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610484565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006106b18484610555565b90506000198114610719578181101561070c5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610484565b6107198484848403610580565b50505050565b6001600160a01b0383166107835760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610484565b6001600160a01b0382166107e55760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610484565b6001600160a01b0383166000908152602081905260409020548181101561085d5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610484565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610719565b6001600160a01b0382166109195760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610484565b806002600082825461092b9190610c24565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0382166109e25760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610484565b6001600160a01b03821660009081526020819052604090205481811015610a565760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610484565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610698565b600060208083528351808285015260005b81811015610ad957858101830151858201604001528201610abd565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610b1157600080fd5b919050565b60008060408385031215610b2957600080fd5b610b3283610afa565b946020939093013593505050565b600080600060608486031215610b5557600080fd5b610b5e84610afa565b9250610b6c60208501610afa565b9150604084013590509250925092565b600060208284031215610b8e57600080fd5b5035919050565b600060208284031215610ba757600080fd5b610bb082610afa565b9392505050565b60008060408385031215610bca57600080fd5b610bd383610afa565b9150610be160208401610afa565b90509250929050565b600181811c90821680610bfe57607f821691505b602082108103610c1e57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103c457634e487b7160e01b600052601160045260246000fdfea26469706673582212208a8e82a679ec260481bb5d10cf7933d8213beeeb9291c42d2ad6b12aa8eb16e264736f6c63430008120033a26469706673582212200154a4130f205f5650af65dc28d67856563d7ace97ac7837c10fce0fae8a0d7564736f6c63430008120033", + Bin: "0x60c06040523480156200001157600080fd5b506040516200408c3803806200408c833981016040819052620000349162000212565b600160005580806001600160a01b038116620000bc5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f727465725570677261646561626c653a207a65726f2074656c6560448201527f706f727465722072656769737472792061646472657373000000000000000000606482015260840160405180910390fd5b6001600160a01b03811660808190526040805163301fd1f560e21b8152905163c07f47d4916004808201926020929091908290030181865afa15801562000107573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200012d919062000244565b600155506200013c33620001c0565b507302000000000000000000000000000000000000056001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000190573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b6919062000244565b60a052506200025e565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000602082840312156200022557600080fd5b81516001600160a01b03811681146200023d57600080fd5b9392505050565b6000602082840312156200025757600080fd5b5051919050565b60805160a051613dd0620002bc600039600081816101c7015281816109cb015281816117ba0152611e8001526000818161015c015281816104620152818161087d01528181610c8b015281816112d901526117fe0152613dd06000f3fe60806040523480156200001157600080fd5b5060043610620001515760003560e01c80638343f66111620000c7578063b9e55da11162000086578063b9e55da11462000329578063c60da612146200035d578063c63d22071462000374578063c868efaa146200038b578063e49cc55314620003a2578063f2fde38b14620003ac57600080fd5b80638343f66114620002885780638c56fcf014620002d05780638da5cb5b14620002e75780639bd9abc014620002f9578063b6109d9d146200031f57600080fd5b80636b47cd9a11620001145780636b47cd9a14620002405780636c7e40d1146200024b578063715018a6146200026457806374971856146200026e5780637a465fd9146200027d57600080fd5b80631a7f5bec1462000156578063367e9584146200019b5780634950d2d014620001c15780635f217bcc14620001f8578063654355681462000203575b600080fd5b6200017e7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b620001b2620001ac36600462002292565b620003c3565b6040516200019291906200237a565b620001e97f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200162000192565b620001e9621e848081565b6200017e620002143660046200238f565b60066020908152600093845260408085208252928452828420905282529020546001600160a01b031681565b620001e9620493e081565b620002626200025c366004620023d6565b62000422565b005b62000262620007f7565b6200017e6005600160991b0181565b620001e962030d4081565b620002bf620002993660046200238f565b600360209081526000938452604080852082529284528284209052825290205460ff1681565b604051901515815260200162000192565b620001b2620002e136600462002438565b6200080f565b6002546001600160a01b03166200017e565b620002bf6200030a3660046200247e565b60056020526000908152604090205460ff1681565b620002626200086a565b620001e96200033a3660046200238f565b600460209081526000938452604080852082529284528284209052825290205481565b620001b26200036e3660046200249e565b6200093f565b62000262620003853660046200250a565b620009bf565b620002626200039c3660046200257f565b62000c73565b620001e960015481565b62000262620003bd3660046200247e565b62000ee8565b6060600085858585604051602001620003e094939291906200260f565b60405160208183030381529060405290506000816040516020016200040792919062002674565b6040516020818303038152906040529150505b949350505050565b6200042c62000f64565b6001600160a01b0384166200045e5760405162461bcd60e51b81526004016200045590620026ae565b60405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d820e64f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620004bf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004e59190620026fa565b9050600082156200051457620004fc848462000fbf565b9050620005146001600160a01b038516838362001135565b60006200065286876001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156200055a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000584919081019062002766565b886001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620005c3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620005ed919081019062002766565b896001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200062c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ac91906200279f565b90506000836001600160a01b031663624488506040518060c001604052808c81526020018b6001600160a01b0316815260200160405180604001604052808b6001600160a01b03168152602001888152508152602001621e84808152602001600067ffffffffffffffff811115620006ce57620006ce620021a0565b604051908082528060200260200182016040528015620006f8578160200160208202803683370190505b508152602001858152506040518263ffffffff1660e01b815260040162000720919062002805565b6020604051808303816000875af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000766919062002887565b60008a81526003602090815260408083206001600160a01b03808e16808652918452828520908d16808652935292819020805460ff1916600117905551929350918b907f110b902745a3d7d6b66732479f01de654a3bc6e501be7c8ba2c3a6f9868cb53990620007d99086815260200190565b60405180910390a450505050620007f06001600055565b5050505050565b6200080162001227565b6200080d600062001283565b565b606060008484846040516020016200082a93929190620028a1565b60405160208183030381529060405290506001816040516020016200085192919062002674565b6040516020818303038152906040529150509392505050565b6200087462001227565b600060015490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015620008da573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000900919062002887565b60018190558110156200093c5760015460405182907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d90600090a35b50565b60408051602081018890526001600160a01b0387811682840152868116606080840191909152908616608083015260a0820185905260c08083018590528351808403909101815260e083019093529190620009a39060029083906101000162002674565b6040516020818303038152906040529150509695505050505050565b620009c962000f64565b7f0000000000000000000000000000000000000000000000000000000000000000870362000a0b5760405162461bcd60e51b81526004016200045590620028c5565b6001600160a01b03841662000a345760405162461bcd60e51b815260040162000455906200290d565b6001600160a01b03861662000a5d5760405162461bcd60e51b81526004016200045590620026ae565b6001600160a01b03851660009081526005602052604090205460ff161562000b485762000a8b818362002966565b831162000aea5760405162461bcd60e51b815260206004820152602660248201527f45524332304272696467653a20696e73756666696369656e7420746f74616c20604482015265185b5bdd5b9d60d21b606482015260840162000455565b62000b426040518060e00160405280898152602001886001600160a01b03168152602001876001600160a01b03168152602001866001600160a01b0316815260200185815260200184815260200183815250620012d5565b62000c5f565b60008781526003602090815260408083206001600160a01b03808b168552908352818420908916845290915290205460ff1662000bda5760405162461bcd60e51b815260206004820152602960248201527f45524332304272696467653a20696e76616c69642062726964676520746f6b656044820152686e206164647265737360b81b606482015260840162000455565b600062000be8868562000fbf565b905082811162000c4d5760405162461bcd60e51b815260206004820152602960248201527f45524332304272696467653a20696e73756666696369656e742061646a757374604482015268195908185b5bdd5b9d60ba1b606482015260840162000455565b62000c5d8888888885886200173c565b505b62000c6a6001600055565b50505050505050565b60015460405163260f846760e11b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634c1f08ce90602401602060405180830381865afa15801562000cdb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d01919062002887565b101562000d6a5760405162461bcd60e51b815260206004820152603060248201527f54656c65706f727465725570677261646561626c653a20696e76616c6964207460448201526f32b632b837b93a32b91039b2b73232b960811b606482015260840162000455565b60008062000d7b838501856200297c565b9092509050600082600281111562000d975762000d976200265e565b0362000ddb576000806000808480602001905181019062000db99190620029ea565b935093509350935062000dd18a8a8686868662001a73565b5050505062000ee0565b600182600281111562000df25762000df26200265e565b0362000e315760008060008380602001905181019062000e13919062002a74565b92509250925062000e28898985858562001be2565b50505062000ee0565b600282600281111562000e485762000e486200265e565b0362000e97576000806000806000808680602001905181019062000e6d919062002abc565b95509550955095509550955062000e8b8c8c88888888888862001d5c565b50505050505062000ee0565b60405162461bcd60e51b815260206004820152601b60248201527f45524332304272696467653a20696e76616c696420616374696f6e0000000000604482015260640162000455565b505050505050565b62000ef262001227565b6001600160a01b03811662000f595760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000455565b6200093c8162001283565b60026000540362000fb85760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162000455565b6002600055565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa15801562001009573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200102f919062002887565b9050620010486001600160a01b03851633308662001f15565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa15801562001090573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620010b6919062002887565b90508181116200111e5760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b606482015260840162000455565b6200112a828262002b2c565b925050505b92915050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562001187573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620011ad919062002887565b620011b9919062002966565b6040516001600160a01b0385166024820152604481018290529091506200122190859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915262001f39565b50505050565b6002546001600160a01b031633146200080d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000455565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d820e64f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001336573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200135c9190620026fa565b90506000808360a0015111156200139f576200138183604001518460a0015162000fbf565b60408401519091506200139f906001600160a01b0316838362001135565b60008360a001518460800151620013b7919062002b2c565b604085810151905163079cc67960e41b815233600482015260248101839052919250906001600160a01b038216906379cc679090604401600060405180830381600087803b1580156200140957600080fd5b505af11580156200141e573d6000803e3d6000fd5b505050506000816001600160a01b031663f72539686040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001463573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001489919062002887565b90506000826001600160a01b0316631a0b79bf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620014cc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620014f29190620026fa565b9050818760000151036200153857806001600160a01b031687602001516001600160a01b031614620015385760405162461bcd60e51b8152600401620004559062002b42565b6000620015be88600001518960200151866001600160a01b03166374d32ad46040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001587573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620015ad9190620026fa565b8b60600151898d60c001516200093f565b90506000876001600160a01b031663624488506040518060c00160405280878152602001866001600160a01b0316815260200160405180604001604052808e604001516001600160a01b031681526020018c8152508152602001620493e08152602001600067ffffffffffffffff8111156200163e576200163e620021a0565b60405190808252806020026020018201604052801562001668578160200160208202803683370190505b508152602001858152506040518263ffffffff1660e01b815260040162001690919062002805565b6020604051808303816000875af1158015620016b0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620016d6919062002887565b90508089600001518a604001516001600160a01b03167f97935c4470efae40c8440c3abfe968a5512232dd375cc974e712f487c2b99c318c602001518d606001518b6040516200172993929190620028a1565b60405180910390a4505050505050505050565b6001600160a01b03841660009081526005602052604090205460ff1615620017b85760405162461bcd60e51b815260206004820152602860248201527f45524332304272696467653a2063616e6e6f742062726964676520777261707060448201526732b2103a37b5b2b760c11b606482015260840162000455565b7f00000000000000000000000000000000000000000000000000000000000000008603620017fa5760405162461bcd60e51b81526004016200045590620028c5565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d820e64f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200185b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018819190620026fa565b90508115620018a057620018a06001600160a01b038616828462001135565b6000620018ae838562002b2c565b60008981526004602090815260408083206001600160a01b03808d168552908352818420908b168452909152812080549293508392909190620018f390849062002966565b9091555060009050620019088787846200080f565b90506000836001600160a01b031663624488506040518060c001604052808d81526020018c6001600160a01b0316815260200160405180604001604052808d6001600160a01b031681526020018a815250815260200162030d408152602001600067ffffffffffffffff811115620019845762001984620021a0565b604051908082528060200260200182016040528015620019ae578160200160208202803683370190505b508152602001858152506040518263ffffffff1660e01b8152600401620019d6919062002805565b6020604051808303816000875af1158015620019f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a1c919062002887565b9050808a896001600160a01b03167f97935c4470efae40c8440c3abfe968a5512232dd375cc974e712f487c2b99c318c8b8860405162001a5f93929190620028a1565b60405180910390a450505050505050505050565b60008681526006602090815260408083206001600160a01b038981168552908352818420888216855290925290912054161562001b045760405162461bcd60e51b815260206004820152602860248201527f45524332304272696467653a2062726964676520746f6b656e20616c72656164604482015267792065786973747360c01b606482015260840162000455565b600086868686868660405162001b1a906200217c565b62001b2b9695949392919062002b91565b604051809103906000f08015801562001b48573d6000803e3d6000fd5b506001600160a01b038181166000818152600560209081526040808320805460ff191660011790558c8352600682528083208c8616808552908352818420958c168085529583529281902080546001600160a01b031916851790555192835293945091928a917fe1c61a845f79534e11924517ddbedc668d0c20e467eafb4d3bd2858e2815f3b5910160405180910390a450505050505050565b62001bec62000f64565b6001600160a01b03821662001c155760405162461bcd60e51b815260040162000455906200290d565b60008581526006602090815260408083206001600160a01b038089168552908352818420878216855290925290912054168062001ca65760405162461bcd60e51b815260206004820152602860248201527f45524332304272696467653a2062726964676520746f6b656e20646f6573206e6044820152671bdd08195e1a5cdd60c21b606482015260840162000455565b6040516340c10f1960e01b81526001600160a01b038481166004830152602482018490528216906340c10f1990604401600060405180830381600087803b15801562001cf157600080fd5b505af115801562001d06573d6000803e3d6000fd5b5050604080516001600160a01b03878116825260208201879052851693507fc0767f158f0d5394b598489a51ed607cd55a8be2dcef113ba1626efcf4c6395492500160405180910390a250620007f06001600055565b62001d6662000f64565b6001600160a01b03831662001d8f5760405162461bcd60e51b815260040162000455906200290d565b6001600160a01b03851662001db85760405162461bcd60e51b81526004016200045590620026ae565b60008881526004602090815260408083206001600160a01b03808c16855290835281842090881684529091529020548281101562001e435760405162461bcd60e51b815260206004820152602160248201527f45524332304272696467653a20696e73756666696369656e742062616c616e636044820152606560f81b606482015260840162000455565b62001e4f838262002b2c565b60008a81526004602090815260408083206001600160a01b03808e168552908352818420908a1684529091529020557f0000000000000000000000000000000000000000000000000000000000000000870362001eee576001600160a01b038616301462001ed15760405162461bcd60e51b8152600401620004559062002b42565b62001ee76001600160a01b038616858562002017565b5062001f00565b62001efe8787878787876200173c565b505b62001f0b6001600055565b5050505050505050565b62001221846323b872dd60e01b858585604051602401620011e993929190620028a1565b600062001f90826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620020499092919063ffffffff16565b80519091501562002012578080602001905181019062001fb1919062002bf0565b620020125760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000455565b505050565b6040516001600160a01b0383166024820152604481018290526200201290849063a9059cbb60e01b90606401620011e9565b60606200041a848460008585600080866001600160a01b0316858760405162002073919062002c14565b60006040518083038185875af1925050503d8060008114620020b2576040519150601f19603f3d011682016040523d82523d6000602084013e620020b7565b606091505b5091509150620020ca87838387620020d5565b979650505050505050565b606083156200214957825160000362002141576001600160a01b0385163b620021415760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000455565b50816200041a565b6200041a8383815115620021605781518083602001fd5b8060405162461bcd60e51b81526004016200045591906200237a565b6111688062002c3383390190565b6001600160a01b03811681146200093c57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715620021e257620021e2620021a0565b604052919050565b600067ffffffffffffffff821115620022075762002207620021a0565b50601f01601f191660200190565b60006200222c6200222684620021ea565b620021b6565b90508281528383830111156200224157600080fd5b828260208301376000602084830101529392505050565b600082601f8301126200226a57600080fd5b6200227b8383356020850162002215565b9392505050565b60ff811681146200093c57600080fd5b60008060008060808587031215620022a957600080fd5b8435620022b6816200218a565b9350602085013567ffffffffffffffff80821115620022d457600080fd5b620022e28883890162002258565b94506040870135915080821115620022f957600080fd5b50620023088782880162002258565b92505060608501356200231b8162002282565b939692955090935050565b60005b838110156200234357818101518382015260200162002329565b50506000910152565b600081518084526200236681602086016020860162002326565b601f01601f19169290920160200192915050565b6020815260006200227b60208301846200234c565b600080600060608486031215620023a557600080fd5b833592506020840135620023b9816200218a565b91506040840135620023cb816200218a565b809150509250925092565b600080600080600060a08688031215620023ef57600080fd5b85359450602086013562002403816200218a565b9350604086013562002415816200218a565b9250606086013562002427816200218a565b949793965091946080013592915050565b6000806000606084860312156200244e57600080fd5b83356200245b816200218a565b925060208401356200246d816200218a565b929592945050506040919091013590565b6000602082840312156200249157600080fd5b81356200227b816200218a565b60008060008060008060c08789031215620024b857600080fd5b863595506020870135620024cc816200218a565b94506040870135620024de816200218a565b93506060870135620024f0816200218a565b9598949750929560808101359460a0909101359350915050565b600080600080600080600060e0888a0312156200252657600080fd5b8735965060208801356200253a816200218a565b955060408801356200254c816200218a565b945060608801356200255e816200218a565b9699959850939660808101359560a0820135955060c0909101359350915050565b600080600080606085870312156200259657600080fd5b843593506020850135620025aa816200218a565b9250604085013567ffffffffffffffff80821115620025c857600080fd5b818701915087601f830112620025dd57600080fd5b813581811115620025ed57600080fd5b8860208285010111156200260057600080fd5b95989497505060200194505050565b6001600160a01b038516815260806020820181905260009062002635908301866200234c565b82810360408401526200264981866200234c565b91505060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b6000600384106200269557634e487b7160e01b600052602160045260246000fd5b838252604060208301526200041a60408301846200234c565b6020808252602c908201527f45524332304272696467653a207a65726f2064657374696e6174696f6e20627260408201526b69646765206164647265737360a01b606082015260800190565b6000602082840312156200270d57600080fd5b81516200227b816200218a565b600082601f8301126200272c57600080fd5b81516200273d6200222682620021ea565b8181528460208386010111156200275357600080fd5b6200041a82602083016020870162002326565b6000602082840312156200277957600080fd5b815167ffffffffffffffff8111156200279157600080fd5b6200041a848285016200271a565b600060208284031215620027b257600080fd5b81516200227b8162002282565b600081518084526020808501945080840160005b83811015620027fa5781516001600160a01b031687529582019590820190600101620027d3565b509495945050505050565b60208152815160208201526000602083015160018060a01b03808216604085015260408501519150808251166060850152506020810151608084015250606083015160a0830152608083015160e060c084015262002868610100840182620027bf565b905060a0840151601f198483030160e08501526200112a82826200234c565b6000602082840312156200289a57600080fd5b5051919050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60208082526028908201527f45524332304272696467653a2063616e6e6f742062726964676520746f20736160408201526736b29031b430b4b760c11b606082015260800190565b60208082526023908201527f45524332304272696467653a207a65726f20726563697069656e74206164647260408201526265737360e81b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b808201808211156200112f576200112f62002950565b600080604083850312156200299057600080fd5b823560038110620029a057600080fd5b9150602083013567ffffffffffffffff811115620029bd57600080fd5b8301601f81018513620029cf57600080fd5b620029e08582356020840162002215565b9150509250929050565b6000806000806080858703121562002a0157600080fd5b845162002a0e816200218a565b602086015190945067ffffffffffffffff8082111562002a2d57600080fd5b62002a3b888389016200271a565b9450604087015191508082111562002a5257600080fd5b5062002a61878288016200271a565b92505060608501516200231b8162002282565b60008060006060848603121562002a8a57600080fd5b835162002a97816200218a565b602085015190935062002aaa816200218a565b80925050604084015190509250925092565b60008060008060008060c0878903121562002ad657600080fd5b86519550602087015162002aea816200218a565b604088015190955062002afd816200218a565b606088015190945062002b10816200218a565b809350506080870151915060a087015190509295509295509295565b818103818111156200112f576200112f62002950565b6020808252602f908201527f45524332304272696467653a20696e76616c69642064657374696e6174696f6e60408201526e20627269646765206164647265737360881b606082015260800190565b8681526001600160a01b0386811660208301528516604082015260c06060820181905260009062002bc5908301866200234c565b828103608084015262002bd981866200234c565b91505060ff831660a0830152979650505050505050565b60006020828403121562002c0357600080fd5b815180151581146200227b57600080fd5b6000825162002c2881846020870162002326565b919091019291505056fe6101206040523480156200001257600080fd5b506040516200116838038062001168833981016040819052620000359162000292565b82826003620000458382620003d5565b506004620000548282620003d5565b50879150620000b690505760405162461bcd60e51b815260206004820152602160248201527f427269646765546f6b656e3a207a65726f20736f7572636520636861696e20696044820152601960fa1b60648201526084015b60405180910390fd5b6001600160a01b0385166200011e5760405162461bcd60e51b815260206004820152602760248201527f427269646765546f6b656e3a207a65726f20736f7572636520627269646765206044820152666164647265737360c81b6064820152608401620000ad565b6001600160a01b038416620001855760405162461bcd60e51b815260206004820152602660248201527f427269646765546f6b656e3a207a65726f20736f75726365206173736574206160448201526564647265737360d01b6064820152608401620000ad565b3360805260a09590955250506001600160a01b0391821660c0521660e05260ff1661010052620004a1565b80516001600160a01b0381168114620001c857600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f557600080fd5b81516001600160401b0380821115620002125762000212620001cd565b604051601f8301601f19908116603f011681019082821181831017156200023d576200023d620001cd565b816040528381526020925086838588010111156200025a57600080fd5b600091505b838210156200027e57858201830151818301840152908201906200025f565b600093810190920192909252949350505050565b60008060008060008060c08789031215620002ac57600080fd5b86519550620002be60208801620001b0565b9450620002ce60408801620001b0565b60608801519094506001600160401b0380821115620002ec57600080fd5b620002fa8a838b01620001e3565b945060808901519150808211156200031157600080fd5b506200032089828a01620001e3565b92505060a087015160ff811681146200033857600080fd5b809150509295509295509295565b600181811c908216806200035b57607f821691505b6020821081036200037c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003d057600081815260208120601f850160051c81016020861015620003ab5750805b601f850160051c820191505b81811015620003cc57828155600101620003b7565b5050505b505050565b81516001600160401b03811115620003f157620003f1620001cd565b620004098162000402845462000346565b8462000382565b602080601f831160018114620004415760008415620004285750858301515b600019600386901b1c1916600185901b178555620003cc565b600085815260208120601f198616915b82811015620004725788860151825594840194600190910190840162000451565b5085821015620004915787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e05161010051610c7b620004ed60003960006101c70152600061025a01526000610173015260006102fc0152600081816102c2015261041b0152610c7b6000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610297578063a9059cbb146102aa578063cd596583146102bd578063dd62ed3e146102e4578063f7253968146102f757600080fd5b806370a082311461022c57806374d32ad41461025557806379cc67901461027c57806395d89b411461028f57600080fd5b806323b872dd116100e957806323b872dd146101ad578063313ce567146101c057806339509351146101f157806340c10f191461020457806342966c681461021957600080fd5b806306fdde031461011b578063095ea7b31461013957806318160ddd1461015c5780631a0b79bf1461016e575b600080fd5b61012361031e565b6040516101309190610aac565b60405180910390f35b61014c610147366004610b16565b6103b0565b6040519015158152602001610130565b6002545b604051908152602001610130565b6101957f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610130565b61014c6101bb366004610b40565b6103ca565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610130565b61014c6101ff366004610b16565b6103ee565b610217610212366004610b16565b610410565b005b610217610227366004610b7c565b61049b565b61016061023a366004610b95565b6001600160a01b031660009081526020819052604090205490565b6101957f000000000000000000000000000000000000000000000000000000000000000081565b61021761028a366004610b16565b6104a8565b6101236104bd565b61014c6102a5366004610b16565b6104cc565b61014c6102b8366004610b16565b610547565b6101957f000000000000000000000000000000000000000000000000000000000000000081565b6101606102f2366004610bb7565b610555565b6101607f000000000000000000000000000000000000000000000000000000000000000081565b60606003805461032d90610bea565b80601f016020809104026020016040519081016040528092919081815260200182805461035990610bea565b80156103a65780601f1061037b576101008083540402835291602001916103a6565b820191906000526020600020905b81548152906001019060200180831161038957829003601f168201915b5050505050905090565b6000336103be818585610580565b60019150505b92915050565b6000336103d88582856106a5565b6103e385858561071f565b506001949350505050565b6000336103be8185856104018383610555565b61040b9190610c24565b610580565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461048d5760405162461bcd60e51b815260206004820152601960248201527f427269646765546f6b656e3a20756e617574686f72697a65640000000000000060448201526064015b60405180910390fd5b61049782826108c3565b5050565b6104a53382610982565b50565b6104b38233836106a5565b6104978282610982565b60606004805461032d90610bea565b600033816104da8286610555565b90508381101561053a5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610484565b6103e38286868403610580565b6000336103be81858561071f565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b0383166105e25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610484565b6001600160a01b0382166106435760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610484565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006106b18484610555565b90506000198114610719578181101561070c5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610484565b6107198484848403610580565b50505050565b6001600160a01b0383166107835760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610484565b6001600160a01b0382166107e55760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610484565b6001600160a01b0383166000908152602081905260409020548181101561085d5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610484565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610719565b6001600160a01b0382166109195760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610484565b806002600082825461092b9190610c24565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0382166109e25760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610484565b6001600160a01b03821660009081526020819052604090205481811015610a565760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610484565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610698565b600060208083528351808285015260005b81811015610ad957858101830151858201604001528201610abd565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610b1157600080fd5b919050565b60008060408385031215610b2957600080fd5b610b3283610afa565b946020939093013593505050565b600080600060608486031215610b5557600080fd5b610b5e84610afa565b9250610b6c60208501610afa565b9150604084013590509250925092565b600060208284031215610b8e57600080fd5b5035919050565b600060208284031215610ba757600080fd5b610bb082610afa565b9392505050565b60008060408385031215610bca57600080fd5b610bd383610afa565b9150610be160208401610afa565b90509250929050565b600181811c90821680610bfe57607f821691505b602082108103610c1e57634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156103c457634e487b7160e01b600052601160045260246000fdfea26469706673582212208a8e82a679ec260481bb5d10cf7933d8213beeeb9291c42d2ad6b12aa8eb16e264736f6c63430008120033a264697066735822122056cceaf1cb8b3bc8415cf4096cf808718ecbf3b4166fe866184bca1de92029e964736f6c63430008120033", } // ERC20BridgeABI is the input ABI used to generate the binding from. diff --git a/abi-bindings/go/CrossChainApplications/ExampleMessenger/ExampleCrossChainMessenger/ExampleCrossChainMessenger.go b/abi-bindings/go/CrossChainApplications/ExampleMessenger/ExampleCrossChainMessenger/ExampleCrossChainMessenger.go index 730343efe..ef4e4e700 100644 --- a/abi-bindings/go/CrossChainApplications/ExampleMessenger/ExampleCrossChainMessenger/ExampleCrossChainMessenger.go +++ b/abi-bindings/go/CrossChainApplications/ExampleMessenger/ExampleCrossChainMessenger/ExampleCrossChainMessenger.go @@ -32,7 +32,7 @@ var ( // ExampleCrossChainMessengerMetaData contains all meta data concerning the ExampleCrossChainMessenger contract. var ExampleCrossChainMessengerMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterRegistryAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\"}],\"name\":\"MinTeleporterVersionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"originBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"ReceiveMessage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"SendMessage\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"originBlockchainID\",\"type\":\"bytes32\"}],\"name\":\"getCurrentMessage\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minTeleporterVersion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"originBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"originSenderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"sendMessage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"teleporterRegistry\",\"outputs\":[{\"internalType\":\"contractTeleporterRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateMinTeleporterVersion\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620015aa380380620015aa833981016040819052620000349162000196565b600160005580806001600160a01b038116620000bc5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f727465725570677261646561626c653a207a65726f2074656c6560448201527f706f727465722072656769737472792061646472657373000000000000000000606482015260840160405180910390fd5b6001600160a01b03811660808190526040805163301fd1f560e21b8152905163c07f47d4916004808201926020929091908290030181865afa15801562000107573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200012d9190620001c8565b600155506200013c3362000144565b5050620001e2565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060208284031215620001a957600080fd5b81516001600160a01b0381168114620001c157600080fd5b9392505050565b600060208284031215620001db57600080fd5b5051919050565b6080516113986200021260003960008181609d0152818161026d01528181610343015261055701526113986000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063b6109d9d11610066578063b6109d9d14610118578063c868efaa14610120578063e49cc55314610133578063f2fde38b1461014a578063f63d09d71461015d57600080fd5b80631a7f5bec14610098578063715018a6146100dc5780638da5cb5b146100e6578063b33fead4146100f7575b600080fd5b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100e4610170565b005b6002546001600160a01b03166100bf565b61010a610105366004610d72565b610184565b6040516100d3929190610ddb565b6100e461025c565b6100e461012e366004610e5d565b61032b565b61013c60015481565b6040519081526020016100d3565b6100e4610158366004610eb9565b6104d3565b61013c61016b366004610edd565b610549565b610178610789565b61018260006107e3565b565b6000818152600360209081526040808320815180830190925280546001600160a01b0316825260018101805460609486949392908401916101c490610f63565b80601f01602080910402602001604051908101604052809291908181526020018280546101f090610f63565b801561023d5780601f106102125761010080835404028352916020019161023d565b820191906000526020600020905b81548152906001019060200180831161022057829003601f168201915b5050505050815250509050806000015181602001519250925050915091565b610264610789565b600060015490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ed9190610f9d565b60018190558110156103285760015460405182907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d90600090a35b50565b60015460405163260f846760e11b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634c1f08ce90602401602060405180830381865afa158015610392573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103b69190610f9d565b10156104225760405162461bcd60e51b815260206004820152603060248201527f54656c65706f727465725570677261646561626c653a20696e76616c6964207460448201526f32b632b837b93a32b91039b2b73232b960811b60648201526084015b60405180910390fd5b600061043082840184610fcc565b6040805180820182526001600160a01b038781168252602080830185815260008b81526003909252939020825181546001600160a01b0319169216919091178155915192935091600182019061048690826110cb565b50905050836001600160a01b0316857f1f5c800b5f2b573929a7948f82a199c2a212851b53a6c5bd703ece23999d24aa836040516104c4919061118b565b60405180910390a35050505050565b6104db610789565b6001600160a01b0381166105405760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610419565b610328816107e3565b6000610553610835565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d820e64f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d7919061119e565b905060008615610601576105eb888861088e565b90506106016001600160a01b03891683836109f8565b886001600160a01b03168a7fa06eff1edd0c66b8dc96d086dda7ba263edf88d7417e6cb15073b5e7bff8a8ca8a848a8a8a6040516106439594939291906111e4565b60405180910390a3816001600160a01b031663624488506040518060c001604052808d81526020018c6001600160a01b0316815260200160405180604001604052808d6001600160a01b03168152602001868152508152602001898152602001600067ffffffffffffffff8111156106bd576106bd610fb6565b6040519080825280602002602001820160405280156106e6578160200160208202803683370190505b50815260200188886040516020016106ff929190611212565b6040516020818303038152906040528152506040518263ffffffff1660e01b815260040161072d919061126a565b6020604051808303816000875af115801561074c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107709190610f9d565b9250505061077e6001600055565b979650505050505050565b6002546001600160a01b031633146101825760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610419565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6002600054036108875760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610419565b6002600055565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa1580156108d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fb9190610f9d565b90506109126001600160a01b038516333086610ae3565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa158015610959573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097d9190610f9d565b90508181116109e35760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b6064820152608401610419565b6109ed82826112fe565b925050505b92915050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015610a49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6d9190610f9d565b610a779190611311565b6040516001600160a01b038516602482015260448101829052909150610add90859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610b1b565b50505050565b6040516001600160a01b0380851660248301528316604482015260648101829052610add9085906323b872dd60e01b90608401610aa6565b6000610b70826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610bf29092919063ffffffff16565b805190915015610bed5780806020019051810190610b8e9190611324565b610bed5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610419565b505050565b6060610c018484600085610c09565b949350505050565b606082471015610c6a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610419565b600080866001600160a01b03168587604051610c869190611346565b60006040518083038185875af1925050503d8060008114610cc3576040519150601f19603f3d011682016040523d82523d6000602084013e610cc8565b606091505b509150915061077e8783838760608315610d43578251600003610d3c576001600160a01b0385163b610d3c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610419565b5081610c01565b610c018383815115610d585781518083602001fd5b8060405162461bcd60e51b8152600401610419919061118b565b600060208284031215610d8457600080fd5b5035919050565b60005b83811015610da6578181015183820152602001610d8e565b50506000910152565b60008151808452610dc7816020860160208601610d8b565b601f01601f19169290920160200192915050565b6001600160a01b0383168152604060208201819052600090610c0190830184610daf565b6001600160a01b038116811461032857600080fd5b60008083601f840112610e2657600080fd5b50813567ffffffffffffffff811115610e3e57600080fd5b602083019150836020828501011115610e5657600080fd5b9250929050565b60008060008060608587031215610e7357600080fd5b843593506020850135610e8581610dff565b9250604085013567ffffffffffffffff811115610ea157600080fd5b610ead87828801610e14565b95989497509550505050565b600060208284031215610ecb57600080fd5b8135610ed681610dff565b9392505050565b600080600080600080600060c0888a031215610ef857600080fd5b873596506020880135610f0a81610dff565b95506040880135610f1a81610dff565b9450606088013593506080880135925060a088013567ffffffffffffffff811115610f4457600080fd5b610f508a828b01610e14565b989b979a50959850939692959293505050565b600181811c90821680610f7757607f821691505b602082108103610f9757634e487b7160e01b600052602260045260246000fd5b50919050565b600060208284031215610faf57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600060208284031215610fde57600080fd5b813567ffffffffffffffff80821115610ff657600080fd5b818401915084601f83011261100a57600080fd5b81358181111561101c5761101c610fb6565b604051601f8201601f19908116603f0116810190838211818310171561104457611044610fb6565b8160405282815287602084870101111561105d57600080fd5b826020860160208301376000928101602001929092525095945050505050565b601f821115610bed57600081815260208120601f850160051c810160208610156110a45750805b601f850160051c820191505b818110156110c3578281556001016110b0565b505050505050565b815167ffffffffffffffff8111156110e5576110e5610fb6565b6110f9816110f38454610f63565b8461107d565b602080601f83116001811461112e57600084156111165750858301515b600019600386901b1c1916600185901b1785556110c3565b600085815260208120601f198616915b8281101561115d5788860151825594840194600190910190840161113e565b508582101561117b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602081526000610ed66020830184610daf565b6000602082840312156111b057600080fd5b8151610ed681610dff565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60018060a01b038616815284602082015283604082015260806060820152600061077e6080830184866111bb565b602081526000610c016020830184866111bb565b600081518084526020808501945080840160005b8381101561125f5781516001600160a01b03168752958201959082019060010161123a565b509495945050505050565b60208152815160208201526000602083015160018060a01b03808216604085015260408501519150808251166060850152506020810151608084015250606083015160a0830152608083015160e060c08401526112cb610100840182611226565b905060a0840151601f198483030160e08501526109ed8282610daf565b634e487b7160e01b600052601160045260246000fd5b818103818111156109f2576109f26112e8565b808201808211156109f2576109f26112e8565b60006020828403121561133657600080fd5b81518015158114610ed657600080fd5b60008251611358818460208701610d8b565b919091019291505056fea26469706673582212200ac3abd1656ec36fe93e285d17b1522d243bab43567aa1d1ae54840806b6eb8d64736f6c63430008120033", + Bin: "0x60a06040523480156200001157600080fd5b50604051620015aa380380620015aa833981016040819052620000349162000196565b600160005580806001600160a01b038116620000bc5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f727465725570677261646561626c653a207a65726f2074656c6560448201527f706f727465722072656769737472792061646472657373000000000000000000606482015260840160405180910390fd5b6001600160a01b03811660808190526040805163301fd1f560e21b8152905163c07f47d4916004808201926020929091908290030181865afa15801562000107573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200012d9190620001c8565b600155506200013c3362000144565b5050620001e2565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060208284031215620001a957600080fd5b81516001600160a01b0381168114620001c157600080fd5b9392505050565b600060208284031215620001db57600080fd5b5051919050565b6080516113986200021260003960008181609d0152818161026d01528181610343015261055701526113986000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063b6109d9d11610066578063b6109d9d14610118578063c868efaa14610120578063e49cc55314610133578063f2fde38b1461014a578063f63d09d71461015d57600080fd5b80631a7f5bec14610098578063715018a6146100dc5780638da5cb5b146100e6578063b33fead4146100f7575b600080fd5b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100e4610170565b005b6002546001600160a01b03166100bf565b61010a610105366004610d72565b610184565b6040516100d3929190610ddb565b6100e461025c565b6100e461012e366004610e5d565b61032b565b61013c60015481565b6040519081526020016100d3565b6100e4610158366004610eb9565b6104d3565b61013c61016b366004610edd565b610549565b610178610789565b61018260006107e3565b565b6000818152600360209081526040808320815180830190925280546001600160a01b0316825260018101805460609486949392908401916101c490610f63565b80601f01602080910402602001604051908101604052809291908181526020018280546101f090610f63565b801561023d5780601f106102125761010080835404028352916020019161023d565b820191906000526020600020905b81548152906001019060200180831161022057829003601f168201915b5050505050815250509050806000015181602001519250925050915091565b610264610789565b600060015490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ed9190610f9d565b60018190558110156103285760015460405182907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d90600090a35b50565b60015460405163260f846760e11b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634c1f08ce90602401602060405180830381865afa158015610392573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103b69190610f9d565b10156104225760405162461bcd60e51b815260206004820152603060248201527f54656c65706f727465725570677261646561626c653a20696e76616c6964207460448201526f32b632b837b93a32b91039b2b73232b960811b60648201526084015b60405180910390fd5b600061043082840184610fcc565b6040805180820182526001600160a01b038781168252602080830185815260008b81526003909252939020825181546001600160a01b0319169216919091178155915192935091600182019061048690826110cb565b50905050836001600160a01b0316857f1f5c800b5f2b573929a7948f82a199c2a212851b53a6c5bd703ece23999d24aa836040516104c4919061118b565b60405180910390a35050505050565b6104db610789565b6001600160a01b0381166105405760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610419565b610328816107e3565b6000610553610835565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d820e64f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d7919061119e565b905060008615610601576105eb888861088e565b90506106016001600160a01b03891683836109f8565b886001600160a01b03168a7fa06eff1edd0c66b8dc96d086dda7ba263edf88d7417e6cb15073b5e7bff8a8ca8a848a8a8a6040516106439594939291906111e4565b60405180910390a3816001600160a01b031663624488506040518060c001604052808d81526020018c6001600160a01b0316815260200160405180604001604052808d6001600160a01b03168152602001868152508152602001898152602001600067ffffffffffffffff8111156106bd576106bd610fb6565b6040519080825280602002602001820160405280156106e6578160200160208202803683370190505b50815260200188886040516020016106ff929190611212565b6040516020818303038152906040528152506040518263ffffffff1660e01b815260040161072d919061126a565b6020604051808303816000875af115801561074c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107709190610f9d565b9250505061077e6001600055565b979650505050505050565b6002546001600160a01b031633146101825760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610419565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6002600054036108875760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610419565b6002600055565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa1580156108d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fb9190610f9d565b90506109126001600160a01b038516333086610ae3565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa158015610959573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097d9190610f9d565b90508181116109e35760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b6064820152608401610419565b6109ed82826112fe565b925050505b92915050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015610a49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6d9190610f9d565b610a779190611311565b6040516001600160a01b038516602482015260448101829052909150610add90859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610b1b565b50505050565b6040516001600160a01b0380851660248301528316604482015260648101829052610add9085906323b872dd60e01b90608401610aa6565b6000610b70826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610bf29092919063ffffffff16565b805190915015610bed5780806020019051810190610b8e9190611324565b610bed5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610419565b505050565b6060610c018484600085610c09565b949350505050565b606082471015610c6a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610419565b600080866001600160a01b03168587604051610c869190611346565b60006040518083038185875af1925050503d8060008114610cc3576040519150601f19603f3d011682016040523d82523d6000602084013e610cc8565b606091505b509150915061077e8783838760608315610d43578251600003610d3c576001600160a01b0385163b610d3c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610419565b5081610c01565b610c018383815115610d585781518083602001fd5b8060405162461bcd60e51b8152600401610419919061118b565b600060208284031215610d8457600080fd5b5035919050565b60005b83811015610da6578181015183820152602001610d8e565b50506000910152565b60008151808452610dc7816020860160208601610d8b565b601f01601f19169290920160200192915050565b6001600160a01b0383168152604060208201819052600090610c0190830184610daf565b6001600160a01b038116811461032857600080fd5b60008083601f840112610e2657600080fd5b50813567ffffffffffffffff811115610e3e57600080fd5b602083019150836020828501011115610e5657600080fd5b9250929050565b60008060008060608587031215610e7357600080fd5b843593506020850135610e8581610dff565b9250604085013567ffffffffffffffff811115610ea157600080fd5b610ead87828801610e14565b95989497509550505050565b600060208284031215610ecb57600080fd5b8135610ed681610dff565b9392505050565b600080600080600080600060c0888a031215610ef857600080fd5b873596506020880135610f0a81610dff565b95506040880135610f1a81610dff565b9450606088013593506080880135925060a088013567ffffffffffffffff811115610f4457600080fd5b610f508a828b01610e14565b989b979a50959850939692959293505050565b600181811c90821680610f7757607f821691505b602082108103610f9757634e487b7160e01b600052602260045260246000fd5b50919050565b600060208284031215610faf57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600060208284031215610fde57600080fd5b813567ffffffffffffffff80821115610ff657600080fd5b818401915084601f83011261100a57600080fd5b81358181111561101c5761101c610fb6565b604051601f8201601f19908116603f0116810190838211818310171561104457611044610fb6565b8160405282815287602084870101111561105d57600080fd5b826020860160208301376000928101602001929092525095945050505050565b601f821115610bed57600081815260208120601f850160051c810160208610156110a45750805b601f850160051c820191505b818110156110c3578281556001016110b0565b505050505050565b815167ffffffffffffffff8111156110e5576110e5610fb6565b6110f9816110f38454610f63565b8461107d565b602080601f83116001811461112e57600084156111165750858301515b600019600386901b1c1916600185901b1785556110c3565b600085815260208120601f198616915b8281101561115d5788860151825594840194600190910190840161113e565b508582101561117b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602081526000610ed66020830184610daf565b6000602082840312156111b057600080fd5b8151610ed681610dff565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60018060a01b038616815284602082015283604082015260806060820152600061077e6080830184866111bb565b602081526000610c016020830184866111bb565b600081518084526020808501945080840160005b8381101561125f5781516001600160a01b03168752958201959082019060010161123a565b509495945050505050565b60208152815160208201526000602083015160018060a01b03808216604085015260408501519150808251166060850152506020810151608084015250606083015160a0830152608083015160e060c08401526112cb610100840182611226565b905060a0840151601f198483030160e08501526109ed8282610daf565b634e487b7160e01b600052601160045260246000fd5b818103818111156109f2576109f26112e8565b808201808211156109f2576109f26112e8565b60006020828403121561133657600080fd5b81518015158114610ed657600080fd5b60008251611358818460208701610d8b565b919091019291505056fea264697066735822122003d1f69ec1a11967893c99560c282458714a9ee9401d228d465633d92b11a6f764736f6c63430008120033", } // ExampleCrossChainMessengerABI is the input ABI used to generate the binding from. diff --git a/abi-bindings/go/CrossChainApplications/NativeTokenBridge/ERC20TokenSource/ERC20TokenSource.go b/abi-bindings/go/CrossChainApplications/NativeTokenBridge/ERC20TokenSource/ERC20TokenSource.go new file mode 100644 index 000000000..bc06d7c95 --- /dev/null +++ b/abi-bindings/go/CrossChainApplications/NativeTokenBridge/ERC20TokenSource/ERC20TokenSource.go @@ -0,0 +1,894 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package erc20tokensource + +import ( + "errors" + "math/big" + "strings" + + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = interfaces.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ERC20TokenSourceMetaData contains all meta data concerning the ERC20TokenSource contract. +var ERC20TokenSourceMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterMessengerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID_\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"nativeTokenDestinationAddress_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"erc20ContractAddress_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"BurnTokens\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"teleporterMessageID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TransferToDestination\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"UnlockTokens\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BURNED_TX_FEES_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINT_NATIVE_TOKENS_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"destinationBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"destinationBurnedTotal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"erc20ContractAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nativeTokenDestinationAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"senderBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"teleporterMessenger\",\"outputs\":[{\"internalType\":\"contractITeleporterMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"totalAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feeAmount\",\"type\":\"uint256\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"}],\"name\":\"transferToDestination\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b50604051620016f1380380620016f183398101604081905262000035916200031d565b60016000556001600160a01b038416620000b15760405162461bcd60e51b815260206004820152603260248201527f4552433230546f6b656e536f757263653a207a65726f2054656c65706f727465604482015271724d657373656e676572206164647265737360701b60648201526084015b60405180910390fd5b6001600160a01b03841660e05282620001155760405162461bcd60e51b81526020600482015260306024820152600080516020620016d183398151915260448201526f1bdb88189b1bd8dad8da185a5b88125160821b6064820152608401620000a8565b7302000000000000000000000000000000000000056001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000168573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200018e919062000371565b8303620002045760405162461bcd60e51b815260206004820152603460248201527f4552433230546f6b656e536f757263653a2063616e6e6f74206272696467652060448201527f776974682073616d6520626c6f636b636861696e0000000000000000000000006064820152608401620000a8565b60808390526001600160a01b038216620002765760405162461bcd60e51b81526020600482015260336024820152600080516020620016d183398151915260448201527f6f6e20636f6e74726163742061646472657373000000000000000000000000006064820152608401620000a8565b6001600160a01b0380831660a0528116620002ea5760405162461bcd60e51b815260206004820152602d60248201527f4552433230546f6b656e536f757263653a207a65726f20455243323020636f6e60448201526c7472616374206164647265737360981b6064820152608401620000a8565b6001600160a01b031660c052506200038b915050565b80516001600160a01b03811681146200031857600080fd5b919050565b600080600080608085870312156200033457600080fd5b6200033f8562000300565b935060208501519250620003566040860162000300565b9150620003666060860162000300565b905092959194509250565b6000602082840312156200038457600080fd5b5051919050565b60805160a05160c05160e0516112ba620004176000396000818160f50152818161029c015281816102d301526104ed015260008181610183015281816101e30152818161027b0152818161036d01528181610a9a0152610c6a01526000818161013e015281816103330152610605015260008181609d0152818161030d015261058201526112ba6000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063b6171f7311610066578063b6171f731461012f578063b8c9091a14610139578063c452165e14610160578063c868efaa1461016b578063e486df151461017e57600080fd5b806341d3014d1461009857806355db3e9e146100d257806387a2edba146100db5780639b3e5803146100f0575b600080fd5b6100bf7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6100bf60015481565b6100ee6100e9366004610e39565b6101a5565b005b6101177f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100c9565b6100bf620186a081565b6101177f000000000000000000000000000000000000000000000000000000000000000081565b610117600160981b81565b6100ee610179366004610ed2565b6104da565b6101177f000000000000000000000000000000000000000000000000000000000000000081565b6101ad610785565b6001600160a01b0385166101dc5760405162461bcd60e51b81526004016101d390610f5b565b60405180910390fd5b60006102087f0000000000000000000000000000000000000000000000000000000000000000866107de565b90508381116102705760405162461bcd60e51b815260206004820152602e60248201527f4552433230546f6b656e536f757263653a20696e73756666696369656e74206160448201526d191a9d5cdd195908185b5bdd5b9d60921b60648201526084016101d3565b83156102c1576102c17f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000086610948565b60006102cd8583610fb9565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663624488506040518060c001604052807f000000000000000000000000000000000000000000000000000000000000000081526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815260200160405180604001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020018b8152508152602001620186a08152602001888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250505090825250604080516001600160a01b038e166020808301919091529181018890529101906060016040516020818303038152906040528152506040518263ffffffff1660e01b81526004016104339190611060565b6020604051808303816000875af1158015610452573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061047691906110de565b905080886001600160a01b0316336001600160a01b03167f2b4e8f08417773e367064a6aea9ca2df303a60876676f70b6c3c5e66b314ca5a856040516104be91815260200190565b60405180910390a45050506104d36001600055565b5050505050565b6104e2610785565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105805760405162461bcd60e51b815260206004820152603b60248201527f4552433230546f6b656e536f757263653a20756e617574686f72697a6564205460448201527f656c65706f727465724d657373656e67657220636f6e7472616374000000000060648201526084016101d3565b7f000000000000000000000000000000000000000000000000000000000000000084146106035760405162461bcd60e51b815260206004820152602b60248201527f4552433230546f6b656e536f757263653a20696e76616c69642064657374696e60448201526a30ba34b7b71031b430b4b760a91b60648201526084016101d3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316146106925760405162461bcd60e51b815260206004820152602560248201527f4552433230546f6b656e536f757263653a20756e617574686f72697a6564207360448201526432b73232b960d91b60648201526084016101d3565b6000806106a18385018561110d565b909250905060008260018111156106ba576106ba6111d5565b036106eb57600080828060200190518101906106d691906111eb565b915091506106e48282610a2d565b5050610773565b60018260018111156106ff576106ff6111d5565b0361072b5760008180602001905181019061071a91906110de565b905061072581610ac4565b50610773565b60405162461bcd60e51b815260206004820181905260248201527f4552433230546f6b656e536f757263653a20696e76616c696420616374696f6e60448201526064016101d3565b505061077f6001600055565b50505050565b6002600054036107d75760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016101d3565b6002600055565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa158015610827573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084b91906110de565b90506108626001600160a01b038516333086610af3565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa1580156108a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108cd91906110de565b90508181116109335760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b60648201526084016101d3565b61093d8282610fb9565b925050505b92915050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015610999573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bd91906110de565b6109c79190611219565b6040516001600160a01b03851660248201526044810182905290915061077f90859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610b2b565b6001600160a01b038216610a535760405162461bcd60e51b81526004016101d390610f5b565b604080516001600160a01b0384168152602081018390527f55aaef8fd8c07238c3618a93c8a1627194187d3b0952908e58f2ab0f944fb407910160405180910390a1610ac07f00000000000000000000000000000000000000000000000000000000000000008383610c02565b5050565b600154811115610af057600060015482610ade9190610fb9565b9050610ae981610c32565b5060018190555b50565b6040516001600160a01b038085166024830152831660448201526064810182905261077f9085906323b872dd60e01b906084016109f6565b6000610b80826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610c949092919063ffffffff16565b805190915015610bfd5780806020019051810190610b9e919061122c565b610bfd5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016101d3565b505050565b6040516001600160a01b038316602482015260448101829052610bfd90849063a9059cbb60e01b906064016109f6565b6040518181527f2cd3fd70cd5a5d6d805e90d22741aa1a84590ace7cf01b244719558d266143829060200160405180910390a1610af07f0000000000000000000000000000000000000000000000000000000000000000600160981b83610c02565b6060610ca38484600085610cab565b949350505050565b606082471015610d0c5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016101d3565b600080866001600160a01b03168587604051610d289190611255565b60006040518083038185875af1925050503d8060008114610d65576040519150601f19603f3d011682016040523d82523d6000602084013e610d6a565b606091505b5091509150610d7b87838387610d86565b979650505050505050565b60608315610df5578251600003610dee576001600160a01b0385163b610dee5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101d3565b5081610ca3565b610ca38383815115610e0a5781518083602001fd5b8060405162461bcd60e51b81526004016101d39190611271565b6001600160a01b0381168114610af057600080fd5b600080600080600060808688031215610e5157600080fd5b8535610e5c81610e24565b94506020860135935060408601359250606086013567ffffffffffffffff80821115610e8757600080fd5b818801915088601f830112610e9b57600080fd5b813581811115610eaa57600080fd5b8960208260051b8501011115610ebf57600080fd5b9699959850939650602001949392505050565b60008060008060608587031215610ee857600080fd5b843593506020850135610efa81610e24565b9250604085013567ffffffffffffffff80821115610f1757600080fd5b818701915087601f830112610f2b57600080fd5b813581811115610f3a57600080fd5b886020828501011115610f4c57600080fd5b95989497505060200194505050565b60208082526028908201527f4552433230546f6b656e536f757263653a207a65726f20726563697069656e74604082015267206164647265737360c01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561094257610942610fa3565b600081518084526020808501945080840160005b838110156110055781516001600160a01b031687529582019590820190600101610fe0565b509495945050505050565b60005b8381101561102b578181015183820152602001611013565b50506000910152565b6000815180845261104c816020860160208601611010565b601f01601f19169290920160200192915050565b60208152815160208201526000602083015160018060a01b03808216604085015260408501519150808251166060850152506020810151608084015250606083015160a0830152608083015160e060c08401526110c1610100840182610fcc565b905060a0840151601f198483030160e085015261093d8282611034565b6000602082840312156110f057600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561112057600080fd5b82356002811061112f57600080fd5b9150602083013567ffffffffffffffff8082111561114c57600080fd5b818501915085601f83011261116057600080fd5b813581811115611172576111726110f7565b604051601f8201601f19908116603f0116810190838211818310171561119a5761119a6110f7565b816040528281528860208487010111156111b357600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b634e487b7160e01b600052602160045260246000fd5b600080604083850312156111fe57600080fd5b825161120981610e24565b6020939093015192949293505050565b8082018082111561094257610942610fa3565b60006020828403121561123e57600080fd5b8151801515811461124e57600080fd5b9392505050565b60008251611267818460208701611010565b9190910192915050565b60208152600061124e602083018461103456fea2646970667358221220ea4f7fe2fb79a487153a86e34946c46d0dc03e1eb717523b03577a4cf4212c9a64736f6c634300081200334552433230546f6b656e536f757263653a207a65726f2064657374696e617469", +} + +// ERC20TokenSourceABI is the input ABI used to generate the binding from. +// Deprecated: Use ERC20TokenSourceMetaData.ABI instead. +var ERC20TokenSourceABI = ERC20TokenSourceMetaData.ABI + +// ERC20TokenSourceBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ERC20TokenSourceMetaData.Bin instead. +var ERC20TokenSourceBin = ERC20TokenSourceMetaData.Bin + +// DeployERC20TokenSource deploys a new Ethereum contract, binding an instance of ERC20TokenSource to it. +func DeployERC20TokenSource(auth *bind.TransactOpts, backend bind.ContractBackend, teleporterMessengerAddress common.Address, destinationBlockchainID_ [32]byte, nativeTokenDestinationAddress_ common.Address, erc20ContractAddress_ common.Address) (common.Address, *types.Transaction, *ERC20TokenSource, error) { + parsed, err := ERC20TokenSourceMetaData.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(ERC20TokenSourceBin), backend, teleporterMessengerAddress, destinationBlockchainID_, nativeTokenDestinationAddress_, erc20ContractAddress_) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ERC20TokenSource{ERC20TokenSourceCaller: ERC20TokenSourceCaller{contract: contract}, ERC20TokenSourceTransactor: ERC20TokenSourceTransactor{contract: contract}, ERC20TokenSourceFilterer: ERC20TokenSourceFilterer{contract: contract}}, nil +} + +// ERC20TokenSource is an auto generated Go binding around an Ethereum contract. +type ERC20TokenSource struct { + ERC20TokenSourceCaller // Read-only binding to the contract + ERC20TokenSourceTransactor // Write-only binding to the contract + ERC20TokenSourceFilterer // Log filterer for contract events +} + +// ERC20TokenSourceCaller is an auto generated read-only Go binding around an Ethereum contract. +type ERC20TokenSourceCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenSourceTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ERC20TokenSourceTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenSourceFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ERC20TokenSourceFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenSourceSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ERC20TokenSourceSession struct { + Contract *ERC20TokenSource // 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 +} + +// ERC20TokenSourceCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ERC20TokenSourceCallerSession struct { + Contract *ERC20TokenSourceCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ERC20TokenSourceTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ERC20TokenSourceTransactorSession struct { + Contract *ERC20TokenSourceTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenSourceRaw is an auto generated low-level Go binding around an Ethereum contract. +type ERC20TokenSourceRaw struct { + Contract *ERC20TokenSource // Generic contract binding to access the raw methods on +} + +// ERC20TokenSourceCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ERC20TokenSourceCallerRaw struct { + Contract *ERC20TokenSourceCaller // Generic read-only contract binding to access the raw methods on +} + +// ERC20TokenSourceTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ERC20TokenSourceTransactorRaw struct { + Contract *ERC20TokenSourceTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewERC20TokenSource creates a new instance of ERC20TokenSource, bound to a specific deployed contract. +func NewERC20TokenSource(address common.Address, backend bind.ContractBackend) (*ERC20TokenSource, error) { + contract, err := bindERC20TokenSource(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ERC20TokenSource{ERC20TokenSourceCaller: ERC20TokenSourceCaller{contract: contract}, ERC20TokenSourceTransactor: ERC20TokenSourceTransactor{contract: contract}, ERC20TokenSourceFilterer: ERC20TokenSourceFilterer{contract: contract}}, nil +} + +// NewERC20TokenSourceCaller creates a new read-only instance of ERC20TokenSource, bound to a specific deployed contract. +func NewERC20TokenSourceCaller(address common.Address, caller bind.ContractCaller) (*ERC20TokenSourceCaller, error) { + contract, err := bindERC20TokenSource(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ERC20TokenSourceCaller{contract: contract}, nil +} + +// NewERC20TokenSourceTransactor creates a new write-only instance of ERC20TokenSource, bound to a specific deployed contract. +func NewERC20TokenSourceTransactor(address common.Address, transactor bind.ContractTransactor) (*ERC20TokenSourceTransactor, error) { + contract, err := bindERC20TokenSource(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ERC20TokenSourceTransactor{contract: contract}, nil +} + +// NewERC20TokenSourceFilterer creates a new log filterer instance of ERC20TokenSource, bound to a specific deployed contract. +func NewERC20TokenSourceFilterer(address common.Address, filterer bind.ContractFilterer) (*ERC20TokenSourceFilterer, error) { + contract, err := bindERC20TokenSource(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ERC20TokenSourceFilterer{contract: contract}, nil +} + +// bindERC20TokenSource binds a generic wrapper to an already deployed contract. +func bindERC20TokenSource(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ERC20TokenSourceMetaData.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 (_ERC20TokenSource *ERC20TokenSourceRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenSource.Contract.ERC20TokenSourceCaller.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 (_ERC20TokenSource *ERC20TokenSourceRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenSource.Contract.ERC20TokenSourceTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenSource *ERC20TokenSourceRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenSource.Contract.ERC20TokenSourceTransactor.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 (_ERC20TokenSource *ERC20TokenSourceCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenSource.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 (_ERC20TokenSource *ERC20TokenSourceTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenSource.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenSource *ERC20TokenSourceTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenSource.Contract.contract.Transact(opts, method, params...) +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_ERC20TokenSource *ERC20TokenSourceCaller) BURNEDTXFEESADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenSource.contract.Call(opts, &out, "BURNED_TX_FEES_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_ERC20TokenSource *ERC20TokenSourceSession) BURNEDTXFEESADDRESS() (common.Address, error) { + return _ERC20TokenSource.Contract.BURNEDTXFEESADDRESS(&_ERC20TokenSource.CallOpts) +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_ERC20TokenSource *ERC20TokenSourceCallerSession) BURNEDTXFEESADDRESS() (common.Address, error) { + return _ERC20TokenSource.Contract.BURNEDTXFEESADDRESS(&_ERC20TokenSource.CallOpts) +} + +// MINTNATIVETOKENSREQUIREDGAS is a free data retrieval call binding the contract method 0xb6171f73. +// +// Solidity: function MINT_NATIVE_TOKENS_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenSource *ERC20TokenSourceCaller) MINTNATIVETOKENSREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenSource.contract.Call(opts, &out, "MINT_NATIVE_TOKENS_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MINTNATIVETOKENSREQUIREDGAS is a free data retrieval call binding the contract method 0xb6171f73. +// +// Solidity: function MINT_NATIVE_TOKENS_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenSource *ERC20TokenSourceSession) MINTNATIVETOKENSREQUIREDGAS() (*big.Int, error) { + return _ERC20TokenSource.Contract.MINTNATIVETOKENSREQUIREDGAS(&_ERC20TokenSource.CallOpts) +} + +// MINTNATIVETOKENSREQUIREDGAS is a free data retrieval call binding the contract method 0xb6171f73. +// +// Solidity: function MINT_NATIVE_TOKENS_REQUIRED_GAS() view returns(uint256) +func (_ERC20TokenSource *ERC20TokenSourceCallerSession) MINTNATIVETOKENSREQUIREDGAS() (*big.Int, error) { + return _ERC20TokenSource.Contract.MINTNATIVETOKENSREQUIREDGAS(&_ERC20TokenSource.CallOpts) +} + +// DestinationBlockchainID is a free data retrieval call binding the contract method 0x41d3014d. +// +// Solidity: function destinationBlockchainID() view returns(bytes32) +func (_ERC20TokenSource *ERC20TokenSourceCaller) DestinationBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenSource.contract.Call(opts, &out, "destinationBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// DestinationBlockchainID is a free data retrieval call binding the contract method 0x41d3014d. +// +// Solidity: function destinationBlockchainID() view returns(bytes32) +func (_ERC20TokenSource *ERC20TokenSourceSession) DestinationBlockchainID() ([32]byte, error) { + return _ERC20TokenSource.Contract.DestinationBlockchainID(&_ERC20TokenSource.CallOpts) +} + +// DestinationBlockchainID is a free data retrieval call binding the contract method 0x41d3014d. +// +// Solidity: function destinationBlockchainID() view returns(bytes32) +func (_ERC20TokenSource *ERC20TokenSourceCallerSession) DestinationBlockchainID() ([32]byte, error) { + return _ERC20TokenSource.Contract.DestinationBlockchainID(&_ERC20TokenSource.CallOpts) +} + +// DestinationBurnedTotal is a free data retrieval call binding the contract method 0x55db3e9e. +// +// Solidity: function destinationBurnedTotal() view returns(uint256) +func (_ERC20TokenSource *ERC20TokenSourceCaller) DestinationBurnedTotal(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenSource.contract.Call(opts, &out, "destinationBurnedTotal") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// DestinationBurnedTotal is a free data retrieval call binding the contract method 0x55db3e9e. +// +// Solidity: function destinationBurnedTotal() view returns(uint256) +func (_ERC20TokenSource *ERC20TokenSourceSession) DestinationBurnedTotal() (*big.Int, error) { + return _ERC20TokenSource.Contract.DestinationBurnedTotal(&_ERC20TokenSource.CallOpts) +} + +// DestinationBurnedTotal is a free data retrieval call binding the contract method 0x55db3e9e. +// +// Solidity: function destinationBurnedTotal() view returns(uint256) +func (_ERC20TokenSource *ERC20TokenSourceCallerSession) DestinationBurnedTotal() (*big.Int, error) { + return _ERC20TokenSource.Contract.DestinationBurnedTotal(&_ERC20TokenSource.CallOpts) +} + +// Erc20ContractAddress is a free data retrieval call binding the contract method 0xe486df15. +// +// Solidity: function erc20ContractAddress() view returns(address) +func (_ERC20TokenSource *ERC20TokenSourceCaller) Erc20ContractAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenSource.contract.Call(opts, &out, "erc20ContractAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Erc20ContractAddress is a free data retrieval call binding the contract method 0xe486df15. +// +// Solidity: function erc20ContractAddress() view returns(address) +func (_ERC20TokenSource *ERC20TokenSourceSession) Erc20ContractAddress() (common.Address, error) { + return _ERC20TokenSource.Contract.Erc20ContractAddress(&_ERC20TokenSource.CallOpts) +} + +// Erc20ContractAddress is a free data retrieval call binding the contract method 0xe486df15. +// +// Solidity: function erc20ContractAddress() view returns(address) +func (_ERC20TokenSource *ERC20TokenSourceCallerSession) Erc20ContractAddress() (common.Address, error) { + return _ERC20TokenSource.Contract.Erc20ContractAddress(&_ERC20TokenSource.CallOpts) +} + +// NativeTokenDestinationAddress is a free data retrieval call binding the contract method 0xb8c9091a. +// +// Solidity: function nativeTokenDestinationAddress() view returns(address) +func (_ERC20TokenSource *ERC20TokenSourceCaller) NativeTokenDestinationAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenSource.contract.Call(opts, &out, "nativeTokenDestinationAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// NativeTokenDestinationAddress is a free data retrieval call binding the contract method 0xb8c9091a. +// +// Solidity: function nativeTokenDestinationAddress() view returns(address) +func (_ERC20TokenSource *ERC20TokenSourceSession) NativeTokenDestinationAddress() (common.Address, error) { + return _ERC20TokenSource.Contract.NativeTokenDestinationAddress(&_ERC20TokenSource.CallOpts) +} + +// NativeTokenDestinationAddress is a free data retrieval call binding the contract method 0xb8c9091a. +// +// Solidity: function nativeTokenDestinationAddress() view returns(address) +func (_ERC20TokenSource *ERC20TokenSourceCallerSession) NativeTokenDestinationAddress() (common.Address, error) { + return _ERC20TokenSource.Contract.NativeTokenDestinationAddress(&_ERC20TokenSource.CallOpts) +} + +// TeleporterMessenger is a free data retrieval call binding the contract method 0x9b3e5803. +// +// Solidity: function teleporterMessenger() view returns(address) +func (_ERC20TokenSource *ERC20TokenSourceCaller) TeleporterMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenSource.contract.Call(opts, &out, "teleporterMessenger") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// TeleporterMessenger is a free data retrieval call binding the contract method 0x9b3e5803. +// +// Solidity: function teleporterMessenger() view returns(address) +func (_ERC20TokenSource *ERC20TokenSourceSession) TeleporterMessenger() (common.Address, error) { + return _ERC20TokenSource.Contract.TeleporterMessenger(&_ERC20TokenSource.CallOpts) +} + +// TeleporterMessenger is a free data retrieval call binding the contract method 0x9b3e5803. +// +// Solidity: function teleporterMessenger() view returns(address) +func (_ERC20TokenSource *ERC20TokenSourceCallerSession) TeleporterMessenger() (common.Address, error) { + return _ERC20TokenSource.Contract.TeleporterMessenger(&_ERC20TokenSource.CallOpts) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 senderBlockchainID, address senderAddress, bytes message) returns() +func (_ERC20TokenSource *ERC20TokenSourceTransactor) ReceiveTeleporterMessage(opts *bind.TransactOpts, senderBlockchainID [32]byte, senderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenSource.contract.Transact(opts, "receiveTeleporterMessage", senderBlockchainID, senderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 senderBlockchainID, address senderAddress, bytes message) returns() +func (_ERC20TokenSource *ERC20TokenSourceSession) ReceiveTeleporterMessage(senderBlockchainID [32]byte, senderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenSource.Contract.ReceiveTeleporterMessage(&_ERC20TokenSource.TransactOpts, senderBlockchainID, senderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 senderBlockchainID, address senderAddress, bytes message) returns() +func (_ERC20TokenSource *ERC20TokenSourceTransactorSession) ReceiveTeleporterMessage(senderBlockchainID [32]byte, senderAddress common.Address, message []byte) (*types.Transaction, error) { + return _ERC20TokenSource.Contract.ReceiveTeleporterMessage(&_ERC20TokenSource.TransactOpts, senderBlockchainID, senderAddress, message) +} + +// TransferToDestination is a paid mutator transaction binding the contract method 0x87a2edba. +// +// Solidity: function transferToDestination(address recipient, uint256 totalAmount, uint256 feeAmount, address[] allowedRelayerAddresses) returns() +func (_ERC20TokenSource *ERC20TokenSourceTransactor) TransferToDestination(opts *bind.TransactOpts, recipient common.Address, totalAmount *big.Int, feeAmount *big.Int, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _ERC20TokenSource.contract.Transact(opts, "transferToDestination", recipient, totalAmount, feeAmount, allowedRelayerAddresses) +} + +// TransferToDestination is a paid mutator transaction binding the contract method 0x87a2edba. +// +// Solidity: function transferToDestination(address recipient, uint256 totalAmount, uint256 feeAmount, address[] allowedRelayerAddresses) returns() +func (_ERC20TokenSource *ERC20TokenSourceSession) TransferToDestination(recipient common.Address, totalAmount *big.Int, feeAmount *big.Int, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _ERC20TokenSource.Contract.TransferToDestination(&_ERC20TokenSource.TransactOpts, recipient, totalAmount, feeAmount, allowedRelayerAddresses) +} + +// TransferToDestination is a paid mutator transaction binding the contract method 0x87a2edba. +// +// Solidity: function transferToDestination(address recipient, uint256 totalAmount, uint256 feeAmount, address[] allowedRelayerAddresses) returns() +func (_ERC20TokenSource *ERC20TokenSourceTransactorSession) TransferToDestination(recipient common.Address, totalAmount *big.Int, feeAmount *big.Int, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _ERC20TokenSource.Contract.TransferToDestination(&_ERC20TokenSource.TransactOpts, recipient, totalAmount, feeAmount, allowedRelayerAddresses) +} + +// ERC20TokenSourceBurnTokensIterator is returned from FilterBurnTokens and is used to iterate over the raw logs and unpacked data for BurnTokens events raised by the ERC20TokenSource contract. +type ERC20TokenSourceBurnTokensIterator struct { + Event *ERC20TokenSourceBurnTokens // 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 interfaces.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 *ERC20TokenSourceBurnTokensIterator) 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(ERC20TokenSourceBurnTokens) + 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(ERC20TokenSourceBurnTokens) + 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 *ERC20TokenSourceBurnTokensIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenSourceBurnTokensIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenSourceBurnTokens represents a BurnTokens event raised by the ERC20TokenSource contract. +type ERC20TokenSourceBurnTokens struct { + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBurnTokens is a free log retrieval operation binding the contract event 0x2cd3fd70cd5a5d6d805e90d22741aa1a84590ace7cf01b244719558d26614382. +// +// Solidity: event BurnTokens(uint256 amount) +func (_ERC20TokenSource *ERC20TokenSourceFilterer) FilterBurnTokens(opts *bind.FilterOpts) (*ERC20TokenSourceBurnTokensIterator, error) { + + logs, sub, err := _ERC20TokenSource.contract.FilterLogs(opts, "BurnTokens") + if err != nil { + return nil, err + } + return &ERC20TokenSourceBurnTokensIterator{contract: _ERC20TokenSource.contract, event: "BurnTokens", logs: logs, sub: sub}, nil +} + +// WatchBurnTokens is a free log subscription operation binding the contract event 0x2cd3fd70cd5a5d6d805e90d22741aa1a84590ace7cf01b244719558d26614382. +// +// Solidity: event BurnTokens(uint256 amount) +func (_ERC20TokenSource *ERC20TokenSourceFilterer) WatchBurnTokens(opts *bind.WatchOpts, sink chan<- *ERC20TokenSourceBurnTokens) (event.Subscription, error) { + + logs, sub, err := _ERC20TokenSource.contract.WatchLogs(opts, "BurnTokens") + 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(ERC20TokenSourceBurnTokens) + if err := _ERC20TokenSource.contract.UnpackLog(event, "BurnTokens", 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 +} + +// ParseBurnTokens is a log parse operation binding the contract event 0x2cd3fd70cd5a5d6d805e90d22741aa1a84590ace7cf01b244719558d26614382. +// +// Solidity: event BurnTokens(uint256 amount) +func (_ERC20TokenSource *ERC20TokenSourceFilterer) ParseBurnTokens(log types.Log) (*ERC20TokenSourceBurnTokens, error) { + event := new(ERC20TokenSourceBurnTokens) + if err := _ERC20TokenSource.contract.UnpackLog(event, "BurnTokens", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenSourceTransferToDestinationIterator is returned from FilterTransferToDestination and is used to iterate over the raw logs and unpacked data for TransferToDestination events raised by the ERC20TokenSource contract. +type ERC20TokenSourceTransferToDestinationIterator struct { + Event *ERC20TokenSourceTransferToDestination // 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 interfaces.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 *ERC20TokenSourceTransferToDestinationIterator) 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(ERC20TokenSourceTransferToDestination) + 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(ERC20TokenSourceTransferToDestination) + 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 *ERC20TokenSourceTransferToDestinationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenSourceTransferToDestinationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenSourceTransferToDestination represents a TransferToDestination event raised by the ERC20TokenSource contract. +type ERC20TokenSourceTransferToDestination struct { + Sender common.Address + Recipient common.Address + TeleporterMessageID *big.Int + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransferToDestination is a free log retrieval operation binding the contract event 0x2b4e8f08417773e367064a6aea9ca2df303a60876676f70b6c3c5e66b314ca5a. +// +// Solidity: event TransferToDestination(address indexed sender, address indexed recipient, uint256 indexed teleporterMessageID, uint256 amount) +func (_ERC20TokenSource *ERC20TokenSourceFilterer) FilterTransferToDestination(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address, teleporterMessageID []*big.Int) (*ERC20TokenSourceTransferToDestinationIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _ERC20TokenSource.contract.FilterLogs(opts, "TransferToDestination", senderRule, recipientRule, teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenSourceTransferToDestinationIterator{contract: _ERC20TokenSource.contract, event: "TransferToDestination", logs: logs, sub: sub}, nil +} + +// WatchTransferToDestination is a free log subscription operation binding the contract event 0x2b4e8f08417773e367064a6aea9ca2df303a60876676f70b6c3c5e66b314ca5a. +// +// Solidity: event TransferToDestination(address indexed sender, address indexed recipient, uint256 indexed teleporterMessageID, uint256 amount) +func (_ERC20TokenSource *ERC20TokenSourceFilterer) WatchTransferToDestination(opts *bind.WatchOpts, sink chan<- *ERC20TokenSourceTransferToDestination, sender []common.Address, recipient []common.Address, teleporterMessageID []*big.Int) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _ERC20TokenSource.contract.WatchLogs(opts, "TransferToDestination", senderRule, recipientRule, teleporterMessageIDRule) + 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(ERC20TokenSourceTransferToDestination) + if err := _ERC20TokenSource.contract.UnpackLog(event, "TransferToDestination", 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 +} + +// ParseTransferToDestination is a log parse operation binding the contract event 0x2b4e8f08417773e367064a6aea9ca2df303a60876676f70b6c3c5e66b314ca5a. +// +// Solidity: event TransferToDestination(address indexed sender, address indexed recipient, uint256 indexed teleporterMessageID, uint256 amount) +func (_ERC20TokenSource *ERC20TokenSourceFilterer) ParseTransferToDestination(log types.Log) (*ERC20TokenSourceTransferToDestination, error) { + event := new(ERC20TokenSourceTransferToDestination) + if err := _ERC20TokenSource.contract.UnpackLog(event, "TransferToDestination", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenSourceUnlockTokensIterator is returned from FilterUnlockTokens and is used to iterate over the raw logs and unpacked data for UnlockTokens events raised by the ERC20TokenSource contract. +type ERC20TokenSourceUnlockTokensIterator struct { + Event *ERC20TokenSourceUnlockTokens // 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 interfaces.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 *ERC20TokenSourceUnlockTokensIterator) 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(ERC20TokenSourceUnlockTokens) + 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(ERC20TokenSourceUnlockTokens) + 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 *ERC20TokenSourceUnlockTokensIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenSourceUnlockTokensIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenSourceUnlockTokens represents a UnlockTokens event raised by the ERC20TokenSource contract. +type ERC20TokenSourceUnlockTokens struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnlockTokens is a free log retrieval operation binding the contract event 0x55aaef8fd8c07238c3618a93c8a1627194187d3b0952908e58f2ab0f944fb407. +// +// Solidity: event UnlockTokens(address recipient, uint256 amount) +func (_ERC20TokenSource *ERC20TokenSourceFilterer) FilterUnlockTokens(opts *bind.FilterOpts) (*ERC20TokenSourceUnlockTokensIterator, error) { + + logs, sub, err := _ERC20TokenSource.contract.FilterLogs(opts, "UnlockTokens") + if err != nil { + return nil, err + } + return &ERC20TokenSourceUnlockTokensIterator{contract: _ERC20TokenSource.contract, event: "UnlockTokens", logs: logs, sub: sub}, nil +} + +// WatchUnlockTokens is a free log subscription operation binding the contract event 0x55aaef8fd8c07238c3618a93c8a1627194187d3b0952908e58f2ab0f944fb407. +// +// Solidity: event UnlockTokens(address recipient, uint256 amount) +func (_ERC20TokenSource *ERC20TokenSourceFilterer) WatchUnlockTokens(opts *bind.WatchOpts, sink chan<- *ERC20TokenSourceUnlockTokens) (event.Subscription, error) { + + logs, sub, err := _ERC20TokenSource.contract.WatchLogs(opts, "UnlockTokens") + 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(ERC20TokenSourceUnlockTokens) + if err := _ERC20TokenSource.contract.UnpackLog(event, "UnlockTokens", 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 +} + +// ParseUnlockTokens is a log parse operation binding the contract event 0x55aaef8fd8c07238c3618a93c8a1627194187d3b0952908e58f2ab0f944fb407. +// +// Solidity: event UnlockTokens(address recipient, uint256 amount) +func (_ERC20TokenSource *ERC20TokenSourceFilterer) ParseUnlockTokens(log types.Log) (*ERC20TokenSourceUnlockTokens, error) { + event := new(ERC20TokenSourceUnlockTokens) + if err := _ERC20TokenSource.contract.UnpackLog(event, "UnlockTokens", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/CrossChainApplications/NativeTokenBridge/NativeTokenDestination/NativeTokenDestination.go b/abi-bindings/go/CrossChainApplications/NativeTokenBridge/NativeTokenDestination/NativeTokenDestination.go new file mode 100644 index 000000000..3ac3a2f87 --- /dev/null +++ b/abi-bindings/go/CrossChainApplications/NativeTokenBridge/NativeTokenDestination/NativeTokenDestination.go @@ -0,0 +1,1232 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package nativetokendestination + +import ( + "errors" + "math/big" + "strings" + + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = interfaces.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// TeleporterFeeInfo is an auto generated low-level Go binding around an user-defined struct. +type TeleporterFeeInfo struct { + FeeTokenAddress common.Address + Amount *big.Int +} + +// NativeTokenDestinationMetaData contains all meta data concerning the NativeTokenDestination contract. +var NativeTokenDestinationMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterMessengerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID_\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"nativeTokenSourceAddress_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"initialReserveImbalance_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remaining\",\"type\":\"uint256\"}],\"name\":\"CollateralAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeTokensMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"teleporterMessageID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"burnAddressBalance\",\"type\":\"uint256\"}],\"name\":\"ReportTotalBurnedTxFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"teleporterMessageID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TransferToSource\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BURNED_TX_FEES_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"BURN_FOR_TRANSFER_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REPORT_BURNED_TOKENS_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TRANSFER_NATIVE_TOKENS_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentReserveImbalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialReserveImbalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isCollateralized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nativeTokenSourceAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"senderBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structTeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"}],\"name\":\"reportTotalBurnedTxFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sourceBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"teleporterMessenger\",\"outputs\":[{\"internalType\":\"contractITeleporterMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalMinted\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structTeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"}],\"name\":\"transferToSource\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x6101206040527302000000000000000000000000000000000000016080523480156200002a57600080fd5b5060405162001bf138038062001bf18339810160408190526200004d9162000350565b60016000556001600160a01b038416620000d45760405162461bcd60e51b815260206004820152603860248201527f4e6174697665546f6b656e44657374696e6174696f6e3a207a65726f2054656c60448201527f65706f727465724d657373656e6765722061646472657373000000000000000060648201526084015b60405180910390fd5b6001600160a01b03841661010052826200013a5760405162461bcd60e51b8152602060048201526031602482015260008051602062001bd18339815191526044820152701c98d948189b1bd8dad8da185a5b881251607a1b6064820152608401620000cb565b7302000000000000000000000000000000000000056001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200018d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b3919062000399565b8303620002295760405162461bcd60e51b815260206004820152603a60248201527f4e6174697665546f6b656e44657374696e6174696f6e3a2063616e6e6f74206260448201527f726964676520776974682073616d6520626c6f636b636861696e0000000000006064820152608401620000cb565b60a08390526001600160a01b0382166200029b5760405162461bcd60e51b8152602060048201526034602482015260008051602062001bd183398151915260448201527f72636520636f6e747261637420616464726573730000000000000000000000006064820152608401620000cb565b6001600160a01b03821660c0526000819003620003215760405162461bcd60e51b815260206004820152603660248201527f4e6174697665546f6b656e44657374696e6174696f6e3a207a65726f20696e6960448201527f7469616c207265736572766520696d62616c616e6365000000000000000000006064820152608401620000cb565b60e081905260015550620003b3915050565b80516001600160a01b03811681146200034b57600080fd5b919050565b600080600080608085870312156200036757600080fd5b620003728562000333565b935060208501519250620003896040860162000333565b6060959095015193969295505050565b600060208284031215620003ac57600080fd5b5051919050565b60805160a05160c05160e0516101005161178c62000445600039600081816102440152818161035c015281816105fe01528181610638015261084801526000818161021001526103060152600081816101b1015281816103bc01528181610698015261096b01526000818161013c015281816103960152818161067201526108e701526000610bdc015261178c6000f3fe6080604052600436106100e75760003560e01c80638ac7dd201161008a578063ab28523011610059578063ab28523014610297578063c452165e146102ae578063c868efaa146102c6578063d30951261461029757600080fd5b80638ac7dd20146101fe5780639b3e580314610232578063a2309ff814610266578063a2a950171461027c57600080fd5b80633a94fe51116100c65780633a94fe511461015e57806349e3284e146101805780635d93f9af1461019f57806375846562146101eb57600080fd5b8062d872ae146100ec57806318160ddd1461011557806329b7b3fd1461012a575b600080fd5b3480156100f857600080fd5b5061010260015481565b6040519081526020015b60405180910390f35b34801561012157600080fd5b506101026102e6565b34801561013657600080fd5b506101027f000000000000000000000000000000000000000000000000000000000000000081565b34801561016a57600080fd5b5061017e61017936600461130a565b610345565b005b34801561018c57600080fd5b506001546040519015815260200161010c565b3480156101ab57600080fd5b506101d37f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161010c565b61017e6101f9366004611376565b610520565b34801561020a57600080fd5b506101027f000000000000000000000000000000000000000000000000000000000000000081565b34801561023e57600080fd5b506101d37f000000000000000000000000000000000000000000000000000000000000000081565b34801561027257600080fd5b5061010260025481565b34801561028857600080fd5b506101d36001600160981b0181565b3480156102a357600080fd5b50610102620186a081565b3480156102ba57600080fd5b506101d3600160981b81565b3480156102d257600080fd5b5061017e6102e13660046113da565b610835565b6000806103006001600160981b0131600160981b31611479565b905060007f00000000000000000000000000000000000000000000000000000000000000006002546103329190611479565b905061033e828261148c565b9250505090565b6000600160981b6001600160a01b031631905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663624488506040518060c001604052807f000000000000000000000000000000000000000000000000000000000000000081526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602001888036038101906103fa919061149f565b8152602001620186a081526020018787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208082018990528251808303820181528284019093529092019161046c91600191606001611555565b6040516020818303038152906040528152506040518263ffffffff1660e01b815260040161049a91906115d0565b6020604051808303816000875af11580156104b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104dd919061164e565b9050807f2550fa6041684d40e635e29e93dde9017d70c25b46aa88393317b5182ed6ae7c8360405161051191815260200190565b60405180910390a25050505050565b610528610c46565b6001600160a01b0384166105575760405162461bcd60e51b815260040161054e90611667565b60405180910390fd5b600154156105c45760405162461bcd60e51b815260206004820152603460248201527f4e6174697665546f6b656e44657374696e6174696f6e3a20636f6e7472616374604482015273081d5b99195c98dbdb1b185d195c985b1a5e995960621b606482015260840161054e565b6000602084013515610623576105ea6105e060208601866116b5565b8560200135610c9f565b90506106236105fc60208601866116b5565b7f000000000000000000000000000000000000000000000000000000000000000083610e09565b6106346001600160981b0134610eee565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663624488506040518060c001604052807f000000000000000000000000000000000000000000000000000000000000000081526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602001888036038101906106d6919061149f565b8152602001620186a081526020018787808060200260200160405190810160405280939291908181526020018383602002808284376000920182905250938552505060405160209384019361074492508d913491016001600160a01b03929092168252602082015260400190565b60408051601f19818403018152908290526107629291602001611555565b6040516020818303038152906040528152506040518263ffffffff1660e01b815260040161079091906115d0565b6020604051808303816000875af11580156107af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d3919061164e565b905080866001600160a01b0316336001600160a01b03167f0322cbb1d3c23f6dbf1deddb3b4ef3ce0f93ae6eec7b44e4f395804104466d143460405161081b91815260200190565b60405180910390a4505061082f6001600055565b50505050565b61083d610c46565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108e55760405162461bcd60e51b815260206004820152604160248201527f4e6174697665546f6b656e44657374696e6174696f6e3a20756e617574686f7260448201527f697a65642054656c65706f727465724d657373656e67657220636f6e747261636064820152601d60fa1b608482015260a40161054e565b7f000000000000000000000000000000000000000000000000000000000000000084146109695760405162461bcd60e51b815260206004820152602c60248201527f4e6174697665546f6b656e44657374696e6174696f6e3a20696e76616c69642060448201526b39b7bab931b29031b430b4b760a11b606482015260840161054e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316146109fe5760405162461bcd60e51b815260206004820152602b60248201527f4e6174697665546f6b656e44657374696e6174696f6e3a20756e617574686f7260448201526a34bd32b21039b2b73232b960a91b606482015260840161054e565b600080610a0d838501856116d9565b90925090506001600160a01b038216610a385760405162461bcd60e51b815260040161054e90611667565b80600003610a9c5760405162461bcd60e51b815260206004820152602b60248201527f4e6174697665546f6b656e44657374696e6174696f6e3a207a65726f2074726160448201526a6e736665722076616c756560a81b606482015260840161054e565b600154819015610b6157600154821115610b055760015460408051918252600060208301527f244160b15e69cc411f041d94ae7fab6f6bba85dade8403216c05ff4b920d5449910160405180910390a1600154610af9908361148c565b60006001559050610b61565b8160016000828254610b17919061148c565b90915550506001546040805184815260208101929092527f244160b15e69cc411f041d94ae7fab6f6bba85dade8403216c05ff4b920d5449910160405180910390a1505050610c3c565b8060026000828254610b739190611479565b90915550506040518181526001600160a01b038416907fd949ea0e9d5db53492d77f28fd5467fb2f6c4f5b88e3350e3c36729b76e99cf29060200160405180910390a26040516327ad555d60e11b81526001600160a01b038481166004830152602482018390527f00000000000000000000000000000000000000000000000000000000000000001690634f5aaaba90604401600060405180830381600087803b158015610c2057600080fd5b505af1158015610c34573d6000803e3d6000fd5b505050505050505b61082f6001600055565b600260005403610c985760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161054e565b6002600055565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa158015610ce8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0c919061164e565b9050610d236001600160a01b03851633308661100c565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa158015610d6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8e919061164e565b9050818111610df45760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b606482015260840161054e565b610dfe828261148c565b925050505b92915050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015610e5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7e919061164e565b610e889190611479565b6040516001600160a01b03851660248201526044810182905290915061082f90859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611044565b80471015610f3e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161054e565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114610f8b576040519150601f19603f3d011682016040523d82523d6000602084013e610f90565b606091505b50509050806110075760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161054e565b505050565b6040516001600160a01b038085166024830152831660448201526064810182905261082f9085906323b872dd60e01b90608401610eb7565b6000611099826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166111169092919063ffffffff16565b80519091501561100757808060200190518101906110b79190611705565b6110075760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161054e565b6060611125848460008561112d565b949350505050565b60608247101561118e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161054e565b600080866001600160a01b031685876040516111aa9190611727565b60006040518083038185875af1925050503d80600081146111e7576040519150601f19603f3d011682016040523d82523d6000602084013e6111ec565b606091505b50915091506111fd87838387611208565b979650505050505050565b60608315611277578251600003611270576001600160a01b0385163b6112705760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161054e565b5081611125565b611125838381511561128c5781518083602001fd5b8060405162461bcd60e51b815260040161054e9190611743565b6000604082840312156112b857600080fd5b50919050565b60008083601f8401126112d057600080fd5b50813567ffffffffffffffff8111156112e857600080fd5b6020830191508360208260051b850101111561130357600080fd5b9250929050565b60008060006060848603121561131f57600080fd5b61132985856112a6565b9250604084013567ffffffffffffffff81111561134557600080fd5b611351868287016112be565b9497909650939450505050565b6001600160a01b038116811461137357600080fd5b50565b6000806000806080858703121561138c57600080fd5b84356113978161135e565b93506113a686602087016112a6565b9250606085013567ffffffffffffffff8111156113c257600080fd5b6113ce878288016112be565b95989497509550505050565b600080600080606085870312156113f057600080fd5b8435935060208501356114028161135e565b9250604085013567ffffffffffffffff8082111561141f57600080fd5b818701915087601f83011261143357600080fd5b81358181111561144257600080fd5b88602082850101111561145457600080fd5b95989497505060200194505050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610e0357610e03611463565b81810381811115610e0357610e03611463565b6000604082840312156114b157600080fd5b6040516040810181811067ffffffffffffffff821117156114e257634e487b7160e01b600052604160045260246000fd5b60405282356114f08161135e565b81526020928301359281019290925250919050565b60005b83811015611520578181015183820152602001611508565b50506000910152565b60008151808452611541816020860160208601611505565b601f01601f19169290920160200192915050565b60006002841061157557634e487b7160e01b600052602160045260246000fd5b838252604060208301526111256040830184611529565b600081518084526020808501945080840160005b838110156115c55781516001600160a01b0316875295820195908201906001016115a0565b509495945050505050565b60208152815160208201526000602083015160018060a01b03808216604085015260408501519150808251166060850152506020810151608084015250606083015160a0830152608083015160e060c084015261163161010084018261158c565b905060a0840151601f198483030160e0850152610dfe8282611529565b60006020828403121561166057600080fd5b5051919050565b6020808252602e908201527f4e6174697665546f6b656e44657374696e6174696f6e3a207a65726f2072656360408201526d697069656e74206164647265737360901b606082015260800190565b6000602082840312156116c757600080fd5b81356116d28161135e565b9392505050565b600080604083850312156116ec57600080fd5b82356116f78161135e565b946020939093013593505050565b60006020828403121561171757600080fd5b815180151581146116d257600080fd5b60008251611739818460208701611505565b9190910192915050565b6020815260006116d2602083018461152956fea26469706673582212205d326fcb3551f8c55e1f7f5b63b34a003743c912c76760197098dab12cb9165764736f6c634300081200334e6174697665546f6b656e44657374696e6174696f6e3a207a65726f20736f75", +} + +// NativeTokenDestinationABI is the input ABI used to generate the binding from. +// Deprecated: Use NativeTokenDestinationMetaData.ABI instead. +var NativeTokenDestinationABI = NativeTokenDestinationMetaData.ABI + +// NativeTokenDestinationBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use NativeTokenDestinationMetaData.Bin instead. +var NativeTokenDestinationBin = NativeTokenDestinationMetaData.Bin + +// DeployNativeTokenDestination deploys a new Ethereum contract, binding an instance of NativeTokenDestination to it. +func DeployNativeTokenDestination(auth *bind.TransactOpts, backend bind.ContractBackend, teleporterMessengerAddress common.Address, sourceBlockchainID_ [32]byte, nativeTokenSourceAddress_ common.Address, initialReserveImbalance_ *big.Int) (common.Address, *types.Transaction, *NativeTokenDestination, error) { + parsed, err := NativeTokenDestinationMetaData.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(NativeTokenDestinationBin), backend, teleporterMessengerAddress, sourceBlockchainID_, nativeTokenSourceAddress_, initialReserveImbalance_) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &NativeTokenDestination{NativeTokenDestinationCaller: NativeTokenDestinationCaller{contract: contract}, NativeTokenDestinationTransactor: NativeTokenDestinationTransactor{contract: contract}, NativeTokenDestinationFilterer: NativeTokenDestinationFilterer{contract: contract}}, nil +} + +// NativeTokenDestination is an auto generated Go binding around an Ethereum contract. +type NativeTokenDestination struct { + NativeTokenDestinationCaller // Read-only binding to the contract + NativeTokenDestinationTransactor // Write-only binding to the contract + NativeTokenDestinationFilterer // Log filterer for contract events +} + +// NativeTokenDestinationCaller is an auto generated read-only Go binding around an Ethereum contract. +type NativeTokenDestinationCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenDestinationTransactor is an auto generated write-only Go binding around an Ethereum contract. +type NativeTokenDestinationTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenDestinationFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type NativeTokenDestinationFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenDestinationSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type NativeTokenDestinationSession struct { + Contract *NativeTokenDestination // 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 +} + +// NativeTokenDestinationCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type NativeTokenDestinationCallerSession struct { + Contract *NativeTokenDestinationCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// NativeTokenDestinationTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type NativeTokenDestinationTransactorSession struct { + Contract *NativeTokenDestinationTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenDestinationRaw is an auto generated low-level Go binding around an Ethereum contract. +type NativeTokenDestinationRaw struct { + Contract *NativeTokenDestination // Generic contract binding to access the raw methods on +} + +// NativeTokenDestinationCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type NativeTokenDestinationCallerRaw struct { + Contract *NativeTokenDestinationCaller // Generic read-only contract binding to access the raw methods on +} + +// NativeTokenDestinationTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type NativeTokenDestinationTransactorRaw struct { + Contract *NativeTokenDestinationTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewNativeTokenDestination creates a new instance of NativeTokenDestination, bound to a specific deployed contract. +func NewNativeTokenDestination(address common.Address, backend bind.ContractBackend) (*NativeTokenDestination, error) { + contract, err := bindNativeTokenDestination(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &NativeTokenDestination{NativeTokenDestinationCaller: NativeTokenDestinationCaller{contract: contract}, NativeTokenDestinationTransactor: NativeTokenDestinationTransactor{contract: contract}, NativeTokenDestinationFilterer: NativeTokenDestinationFilterer{contract: contract}}, nil +} + +// NewNativeTokenDestinationCaller creates a new read-only instance of NativeTokenDestination, bound to a specific deployed contract. +func NewNativeTokenDestinationCaller(address common.Address, caller bind.ContractCaller) (*NativeTokenDestinationCaller, error) { + contract, err := bindNativeTokenDestination(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NativeTokenDestinationCaller{contract: contract}, nil +} + +// NewNativeTokenDestinationTransactor creates a new write-only instance of NativeTokenDestination, bound to a specific deployed contract. +func NewNativeTokenDestinationTransactor(address common.Address, transactor bind.ContractTransactor) (*NativeTokenDestinationTransactor, error) { + contract, err := bindNativeTokenDestination(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NativeTokenDestinationTransactor{contract: contract}, nil +} + +// NewNativeTokenDestinationFilterer creates a new log filterer instance of NativeTokenDestination, bound to a specific deployed contract. +func NewNativeTokenDestinationFilterer(address common.Address, filterer bind.ContractFilterer) (*NativeTokenDestinationFilterer, error) { + contract, err := bindNativeTokenDestination(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NativeTokenDestinationFilterer{contract: contract}, nil +} + +// bindNativeTokenDestination binds a generic wrapper to an already deployed contract. +func bindNativeTokenDestination(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := NativeTokenDestinationMetaData.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 (_NativeTokenDestination *NativeTokenDestinationRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenDestination.Contract.NativeTokenDestinationCaller.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 (_NativeTokenDestination *NativeTokenDestinationRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenDestination.Contract.NativeTokenDestinationTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenDestination *NativeTokenDestinationRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenDestination.Contract.NativeTokenDestinationTransactor.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 (_NativeTokenDestination *NativeTokenDestinationCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenDestination.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 (_NativeTokenDestination *NativeTokenDestinationTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenDestination.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenDestination *NativeTokenDestinationTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenDestination.Contract.contract.Transact(opts, method, params...) +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_NativeTokenDestination *NativeTokenDestinationCaller) BURNEDTXFEESADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenDestination.contract.Call(opts, &out, "BURNED_TX_FEES_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_NativeTokenDestination *NativeTokenDestinationSession) BURNEDTXFEESADDRESS() (common.Address, error) { + return _NativeTokenDestination.Contract.BURNEDTXFEESADDRESS(&_NativeTokenDestination.CallOpts) +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_NativeTokenDestination *NativeTokenDestinationCallerSession) BURNEDTXFEESADDRESS() (common.Address, error) { + return _NativeTokenDestination.Contract.BURNEDTXFEESADDRESS(&_NativeTokenDestination.CallOpts) +} + +// BURNFORTRANSFERADDRESS is a free data retrieval call binding the contract method 0xa2a95017. +// +// Solidity: function BURN_FOR_TRANSFER_ADDRESS() view returns(address) +func (_NativeTokenDestination *NativeTokenDestinationCaller) BURNFORTRANSFERADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenDestination.contract.Call(opts, &out, "BURN_FOR_TRANSFER_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// BURNFORTRANSFERADDRESS is a free data retrieval call binding the contract method 0xa2a95017. +// +// Solidity: function BURN_FOR_TRANSFER_ADDRESS() view returns(address) +func (_NativeTokenDestination *NativeTokenDestinationSession) BURNFORTRANSFERADDRESS() (common.Address, error) { + return _NativeTokenDestination.Contract.BURNFORTRANSFERADDRESS(&_NativeTokenDestination.CallOpts) +} + +// BURNFORTRANSFERADDRESS is a free data retrieval call binding the contract method 0xa2a95017. +// +// Solidity: function BURN_FOR_TRANSFER_ADDRESS() view returns(address) +func (_NativeTokenDestination *NativeTokenDestinationCallerSession) BURNFORTRANSFERADDRESS() (common.Address, error) { + return _NativeTokenDestination.Contract.BURNFORTRANSFERADDRESS(&_NativeTokenDestination.CallOpts) +} + +// REPORTBURNEDTOKENSREQUIREDGAS is a free data retrieval call binding the contract method 0xd3095126. +// +// Solidity: function REPORT_BURNED_TOKENS_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationCaller) REPORTBURNEDTOKENSREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenDestination.contract.Call(opts, &out, "REPORT_BURNED_TOKENS_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// REPORTBURNEDTOKENSREQUIREDGAS is a free data retrieval call binding the contract method 0xd3095126. +// +// Solidity: function REPORT_BURNED_TOKENS_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationSession) REPORTBURNEDTOKENSREQUIREDGAS() (*big.Int, error) { + return _NativeTokenDestination.Contract.REPORTBURNEDTOKENSREQUIREDGAS(&_NativeTokenDestination.CallOpts) +} + +// REPORTBURNEDTOKENSREQUIREDGAS is a free data retrieval call binding the contract method 0xd3095126. +// +// Solidity: function REPORT_BURNED_TOKENS_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationCallerSession) REPORTBURNEDTOKENSREQUIREDGAS() (*big.Int, error) { + return _NativeTokenDestination.Contract.REPORTBURNEDTOKENSREQUIREDGAS(&_NativeTokenDestination.CallOpts) +} + +// TRANSFERNATIVETOKENSREQUIREDGAS is a free data retrieval call binding the contract method 0xab285230. +// +// Solidity: function TRANSFER_NATIVE_TOKENS_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationCaller) TRANSFERNATIVETOKENSREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenDestination.contract.Call(opts, &out, "TRANSFER_NATIVE_TOKENS_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TRANSFERNATIVETOKENSREQUIREDGAS is a free data retrieval call binding the contract method 0xab285230. +// +// Solidity: function TRANSFER_NATIVE_TOKENS_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationSession) TRANSFERNATIVETOKENSREQUIREDGAS() (*big.Int, error) { + return _NativeTokenDestination.Contract.TRANSFERNATIVETOKENSREQUIREDGAS(&_NativeTokenDestination.CallOpts) +} + +// TRANSFERNATIVETOKENSREQUIREDGAS is a free data retrieval call binding the contract method 0xab285230. +// +// Solidity: function TRANSFER_NATIVE_TOKENS_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationCallerSession) TRANSFERNATIVETOKENSREQUIREDGAS() (*big.Int, error) { + return _NativeTokenDestination.Contract.TRANSFERNATIVETOKENSREQUIREDGAS(&_NativeTokenDestination.CallOpts) +} + +// CurrentReserveImbalance is a free data retrieval call binding the contract method 0x00d872ae. +// +// Solidity: function currentReserveImbalance() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationCaller) CurrentReserveImbalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenDestination.contract.Call(opts, &out, "currentReserveImbalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// CurrentReserveImbalance is a free data retrieval call binding the contract method 0x00d872ae. +// +// Solidity: function currentReserveImbalance() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationSession) CurrentReserveImbalance() (*big.Int, error) { + return _NativeTokenDestination.Contract.CurrentReserveImbalance(&_NativeTokenDestination.CallOpts) +} + +// CurrentReserveImbalance is a free data retrieval call binding the contract method 0x00d872ae. +// +// Solidity: function currentReserveImbalance() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationCallerSession) CurrentReserveImbalance() (*big.Int, error) { + return _NativeTokenDestination.Contract.CurrentReserveImbalance(&_NativeTokenDestination.CallOpts) +} + +// InitialReserveImbalance is a free data retrieval call binding the contract method 0x8ac7dd20. +// +// Solidity: function initialReserveImbalance() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationCaller) InitialReserveImbalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenDestination.contract.Call(opts, &out, "initialReserveImbalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// InitialReserveImbalance is a free data retrieval call binding the contract method 0x8ac7dd20. +// +// Solidity: function initialReserveImbalance() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationSession) InitialReserveImbalance() (*big.Int, error) { + return _NativeTokenDestination.Contract.InitialReserveImbalance(&_NativeTokenDestination.CallOpts) +} + +// InitialReserveImbalance is a free data retrieval call binding the contract method 0x8ac7dd20. +// +// Solidity: function initialReserveImbalance() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationCallerSession) InitialReserveImbalance() (*big.Int, error) { + return _NativeTokenDestination.Contract.InitialReserveImbalance(&_NativeTokenDestination.CallOpts) +} + +// IsCollateralized is a free data retrieval call binding the contract method 0x49e3284e. +// +// Solidity: function isCollateralized() view returns(bool) +func (_NativeTokenDestination *NativeTokenDestinationCaller) IsCollateralized(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _NativeTokenDestination.contract.Call(opts, &out, "isCollateralized") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsCollateralized is a free data retrieval call binding the contract method 0x49e3284e. +// +// Solidity: function isCollateralized() view returns(bool) +func (_NativeTokenDestination *NativeTokenDestinationSession) IsCollateralized() (bool, error) { + return _NativeTokenDestination.Contract.IsCollateralized(&_NativeTokenDestination.CallOpts) +} + +// IsCollateralized is a free data retrieval call binding the contract method 0x49e3284e. +// +// Solidity: function isCollateralized() view returns(bool) +func (_NativeTokenDestination *NativeTokenDestinationCallerSession) IsCollateralized() (bool, error) { + return _NativeTokenDestination.Contract.IsCollateralized(&_NativeTokenDestination.CallOpts) +} + +// NativeTokenSourceAddress is a free data retrieval call binding the contract method 0x5d93f9af. +// +// Solidity: function nativeTokenSourceAddress() view returns(address) +func (_NativeTokenDestination *NativeTokenDestinationCaller) NativeTokenSourceAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenDestination.contract.Call(opts, &out, "nativeTokenSourceAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// NativeTokenSourceAddress is a free data retrieval call binding the contract method 0x5d93f9af. +// +// Solidity: function nativeTokenSourceAddress() view returns(address) +func (_NativeTokenDestination *NativeTokenDestinationSession) NativeTokenSourceAddress() (common.Address, error) { + return _NativeTokenDestination.Contract.NativeTokenSourceAddress(&_NativeTokenDestination.CallOpts) +} + +// NativeTokenSourceAddress is a free data retrieval call binding the contract method 0x5d93f9af. +// +// Solidity: function nativeTokenSourceAddress() view returns(address) +func (_NativeTokenDestination *NativeTokenDestinationCallerSession) NativeTokenSourceAddress() (common.Address, error) { + return _NativeTokenDestination.Contract.NativeTokenSourceAddress(&_NativeTokenDestination.CallOpts) +} + +// SourceBlockchainID is a free data retrieval call binding the contract method 0x29b7b3fd. +// +// Solidity: function sourceBlockchainID() view returns(bytes32) +func (_NativeTokenDestination *NativeTokenDestinationCaller) SourceBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenDestination.contract.Call(opts, &out, "sourceBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// SourceBlockchainID is a free data retrieval call binding the contract method 0x29b7b3fd. +// +// Solidity: function sourceBlockchainID() view returns(bytes32) +func (_NativeTokenDestination *NativeTokenDestinationSession) SourceBlockchainID() ([32]byte, error) { + return _NativeTokenDestination.Contract.SourceBlockchainID(&_NativeTokenDestination.CallOpts) +} + +// SourceBlockchainID is a free data retrieval call binding the contract method 0x29b7b3fd. +// +// Solidity: function sourceBlockchainID() view returns(bytes32) +func (_NativeTokenDestination *NativeTokenDestinationCallerSession) SourceBlockchainID() ([32]byte, error) { + return _NativeTokenDestination.Contract.SourceBlockchainID(&_NativeTokenDestination.CallOpts) +} + +// TeleporterMessenger is a free data retrieval call binding the contract method 0x9b3e5803. +// +// Solidity: function teleporterMessenger() view returns(address) +func (_NativeTokenDestination *NativeTokenDestinationCaller) TeleporterMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenDestination.contract.Call(opts, &out, "teleporterMessenger") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// TeleporterMessenger is a free data retrieval call binding the contract method 0x9b3e5803. +// +// Solidity: function teleporterMessenger() view returns(address) +func (_NativeTokenDestination *NativeTokenDestinationSession) TeleporterMessenger() (common.Address, error) { + return _NativeTokenDestination.Contract.TeleporterMessenger(&_NativeTokenDestination.CallOpts) +} + +// TeleporterMessenger is a free data retrieval call binding the contract method 0x9b3e5803. +// +// Solidity: function teleporterMessenger() view returns(address) +func (_NativeTokenDestination *NativeTokenDestinationCallerSession) TeleporterMessenger() (common.Address, error) { + return _NativeTokenDestination.Contract.TeleporterMessenger(&_NativeTokenDestination.CallOpts) +} + +// TotalMinted is a free data retrieval call binding the contract method 0xa2309ff8. +// +// Solidity: function totalMinted() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationCaller) TotalMinted(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenDestination.contract.Call(opts, &out, "totalMinted") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalMinted is a free data retrieval call binding the contract method 0xa2309ff8. +// +// Solidity: function totalMinted() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationSession) TotalMinted() (*big.Int, error) { + return _NativeTokenDestination.Contract.TotalMinted(&_NativeTokenDestination.CallOpts) +} + +// TotalMinted is a free data retrieval call binding the contract method 0xa2309ff8. +// +// Solidity: function totalMinted() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationCallerSession) TotalMinted() (*big.Int, error) { + return _NativeTokenDestination.Contract.TotalMinted(&_NativeTokenDestination.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenDestination.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationSession) TotalSupply() (*big.Int, error) { + return _NativeTokenDestination.Contract.TotalSupply(&_NativeTokenDestination.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_NativeTokenDestination *NativeTokenDestinationCallerSession) TotalSupply() (*big.Int, error) { + return _NativeTokenDestination.Contract.TotalSupply(&_NativeTokenDestination.CallOpts) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 senderBlockchainID, address senderAddress, bytes message) returns() +func (_NativeTokenDestination *NativeTokenDestinationTransactor) ReceiveTeleporterMessage(opts *bind.TransactOpts, senderBlockchainID [32]byte, senderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenDestination.contract.Transact(opts, "receiveTeleporterMessage", senderBlockchainID, senderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 senderBlockchainID, address senderAddress, bytes message) returns() +func (_NativeTokenDestination *NativeTokenDestinationSession) ReceiveTeleporterMessage(senderBlockchainID [32]byte, senderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenDestination.Contract.ReceiveTeleporterMessage(&_NativeTokenDestination.TransactOpts, senderBlockchainID, senderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 senderBlockchainID, address senderAddress, bytes message) returns() +func (_NativeTokenDestination *NativeTokenDestinationTransactorSession) ReceiveTeleporterMessage(senderBlockchainID [32]byte, senderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenDestination.Contract.ReceiveTeleporterMessage(&_NativeTokenDestination.TransactOpts, senderBlockchainID, senderAddress, message) +} + +// ReportTotalBurnedTxFees is a paid mutator transaction binding the contract method 0x3a94fe51. +// +// Solidity: function reportTotalBurnedTxFees((address,uint256) feeInfo, address[] allowedRelayerAddresses) returns() +func (_NativeTokenDestination *NativeTokenDestinationTransactor) ReportTotalBurnedTxFees(opts *bind.TransactOpts, feeInfo TeleporterFeeInfo, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _NativeTokenDestination.contract.Transact(opts, "reportTotalBurnedTxFees", feeInfo, allowedRelayerAddresses) +} + +// ReportTotalBurnedTxFees is a paid mutator transaction binding the contract method 0x3a94fe51. +// +// Solidity: function reportTotalBurnedTxFees((address,uint256) feeInfo, address[] allowedRelayerAddresses) returns() +func (_NativeTokenDestination *NativeTokenDestinationSession) ReportTotalBurnedTxFees(feeInfo TeleporterFeeInfo, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _NativeTokenDestination.Contract.ReportTotalBurnedTxFees(&_NativeTokenDestination.TransactOpts, feeInfo, allowedRelayerAddresses) +} + +// ReportTotalBurnedTxFees is a paid mutator transaction binding the contract method 0x3a94fe51. +// +// Solidity: function reportTotalBurnedTxFees((address,uint256) feeInfo, address[] allowedRelayerAddresses) returns() +func (_NativeTokenDestination *NativeTokenDestinationTransactorSession) ReportTotalBurnedTxFees(feeInfo TeleporterFeeInfo, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _NativeTokenDestination.Contract.ReportTotalBurnedTxFees(&_NativeTokenDestination.TransactOpts, feeInfo, allowedRelayerAddresses) +} + +// TransferToSource is a paid mutator transaction binding the contract method 0x75846562. +// +// Solidity: function transferToSource(address recipient, (address,uint256) feeInfo, address[] allowedRelayerAddresses) payable returns() +func (_NativeTokenDestination *NativeTokenDestinationTransactor) TransferToSource(opts *bind.TransactOpts, recipient common.Address, feeInfo TeleporterFeeInfo, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _NativeTokenDestination.contract.Transact(opts, "transferToSource", recipient, feeInfo, allowedRelayerAddresses) +} + +// TransferToSource is a paid mutator transaction binding the contract method 0x75846562. +// +// Solidity: function transferToSource(address recipient, (address,uint256) feeInfo, address[] allowedRelayerAddresses) payable returns() +func (_NativeTokenDestination *NativeTokenDestinationSession) TransferToSource(recipient common.Address, feeInfo TeleporterFeeInfo, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _NativeTokenDestination.Contract.TransferToSource(&_NativeTokenDestination.TransactOpts, recipient, feeInfo, allowedRelayerAddresses) +} + +// TransferToSource is a paid mutator transaction binding the contract method 0x75846562. +// +// Solidity: function transferToSource(address recipient, (address,uint256) feeInfo, address[] allowedRelayerAddresses) payable returns() +func (_NativeTokenDestination *NativeTokenDestinationTransactorSession) TransferToSource(recipient common.Address, feeInfo TeleporterFeeInfo, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _NativeTokenDestination.Contract.TransferToSource(&_NativeTokenDestination.TransactOpts, recipient, feeInfo, allowedRelayerAddresses) +} + +// NativeTokenDestinationCollateralAddedIterator is returned from FilterCollateralAdded and is used to iterate over the raw logs and unpacked data for CollateralAdded events raised by the NativeTokenDestination contract. +type NativeTokenDestinationCollateralAddedIterator struct { + Event *NativeTokenDestinationCollateralAdded // 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 interfaces.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 *NativeTokenDestinationCollateralAddedIterator) 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(NativeTokenDestinationCollateralAdded) + 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(NativeTokenDestinationCollateralAdded) + 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 *NativeTokenDestinationCollateralAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenDestinationCollateralAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenDestinationCollateralAdded represents a CollateralAdded event raised by the NativeTokenDestination contract. +type NativeTokenDestinationCollateralAdded struct { + Amount *big.Int + Remaining *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCollateralAdded is a free log retrieval operation binding the contract event 0x244160b15e69cc411f041d94ae7fab6f6bba85dade8403216c05ff4b920d5449. +// +// Solidity: event CollateralAdded(uint256 amount, uint256 remaining) +func (_NativeTokenDestination *NativeTokenDestinationFilterer) FilterCollateralAdded(opts *bind.FilterOpts) (*NativeTokenDestinationCollateralAddedIterator, error) { + + logs, sub, err := _NativeTokenDestination.contract.FilterLogs(opts, "CollateralAdded") + if err != nil { + return nil, err + } + return &NativeTokenDestinationCollateralAddedIterator{contract: _NativeTokenDestination.contract, event: "CollateralAdded", logs: logs, sub: sub}, nil +} + +// WatchCollateralAdded is a free log subscription operation binding the contract event 0x244160b15e69cc411f041d94ae7fab6f6bba85dade8403216c05ff4b920d5449. +// +// Solidity: event CollateralAdded(uint256 amount, uint256 remaining) +func (_NativeTokenDestination *NativeTokenDestinationFilterer) WatchCollateralAdded(opts *bind.WatchOpts, sink chan<- *NativeTokenDestinationCollateralAdded) (event.Subscription, error) { + + logs, sub, err := _NativeTokenDestination.contract.WatchLogs(opts, "CollateralAdded") + 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(NativeTokenDestinationCollateralAdded) + if err := _NativeTokenDestination.contract.UnpackLog(event, "CollateralAdded", 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 +} + +// ParseCollateralAdded is a log parse operation binding the contract event 0x244160b15e69cc411f041d94ae7fab6f6bba85dade8403216c05ff4b920d5449. +// +// Solidity: event CollateralAdded(uint256 amount, uint256 remaining) +func (_NativeTokenDestination *NativeTokenDestinationFilterer) ParseCollateralAdded(log types.Log) (*NativeTokenDestinationCollateralAdded, error) { + event := new(NativeTokenDestinationCollateralAdded) + if err := _NativeTokenDestination.contract.UnpackLog(event, "CollateralAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenDestinationNativeTokensMintedIterator is returned from FilterNativeTokensMinted and is used to iterate over the raw logs and unpacked data for NativeTokensMinted events raised by the NativeTokenDestination contract. +type NativeTokenDestinationNativeTokensMintedIterator struct { + Event *NativeTokenDestinationNativeTokensMinted // 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 interfaces.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 *NativeTokenDestinationNativeTokensMintedIterator) 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(NativeTokenDestinationNativeTokensMinted) + 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(NativeTokenDestinationNativeTokensMinted) + 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 *NativeTokenDestinationNativeTokensMintedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenDestinationNativeTokensMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenDestinationNativeTokensMinted represents a NativeTokensMinted event raised by the NativeTokenDestination contract. +type NativeTokenDestinationNativeTokensMinted struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNativeTokensMinted is a free log retrieval operation binding the contract event 0xd949ea0e9d5db53492d77f28fd5467fb2f6c4f5b88e3350e3c36729b76e99cf2. +// +// Solidity: event NativeTokensMinted(address indexed recipient, uint256 amount) +func (_NativeTokenDestination *NativeTokenDestinationFilterer) FilterNativeTokensMinted(opts *bind.FilterOpts, recipient []common.Address) (*NativeTokenDestinationNativeTokensMintedIterator, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _NativeTokenDestination.contract.FilterLogs(opts, "NativeTokensMinted", recipientRule) + if err != nil { + return nil, err + } + return &NativeTokenDestinationNativeTokensMintedIterator{contract: _NativeTokenDestination.contract, event: "NativeTokensMinted", logs: logs, sub: sub}, nil +} + +// WatchNativeTokensMinted is a free log subscription operation binding the contract event 0xd949ea0e9d5db53492d77f28fd5467fb2f6c4f5b88e3350e3c36729b76e99cf2. +// +// Solidity: event NativeTokensMinted(address indexed recipient, uint256 amount) +func (_NativeTokenDestination *NativeTokenDestinationFilterer) WatchNativeTokensMinted(opts *bind.WatchOpts, sink chan<- *NativeTokenDestinationNativeTokensMinted, recipient []common.Address) (event.Subscription, error) { + + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _NativeTokenDestination.contract.WatchLogs(opts, "NativeTokensMinted", recipientRule) + 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(NativeTokenDestinationNativeTokensMinted) + if err := _NativeTokenDestination.contract.UnpackLog(event, "NativeTokensMinted", 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 +} + +// ParseNativeTokensMinted is a log parse operation binding the contract event 0xd949ea0e9d5db53492d77f28fd5467fb2f6c4f5b88e3350e3c36729b76e99cf2. +// +// Solidity: event NativeTokensMinted(address indexed recipient, uint256 amount) +func (_NativeTokenDestination *NativeTokenDestinationFilterer) ParseNativeTokensMinted(log types.Log) (*NativeTokenDestinationNativeTokensMinted, error) { + event := new(NativeTokenDestinationNativeTokensMinted) + if err := _NativeTokenDestination.contract.UnpackLog(event, "NativeTokensMinted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenDestinationReportTotalBurnedTxFeesIterator is returned from FilterReportTotalBurnedTxFees and is used to iterate over the raw logs and unpacked data for ReportTotalBurnedTxFees events raised by the NativeTokenDestination contract. +type NativeTokenDestinationReportTotalBurnedTxFeesIterator struct { + Event *NativeTokenDestinationReportTotalBurnedTxFees // 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 interfaces.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 *NativeTokenDestinationReportTotalBurnedTxFeesIterator) 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(NativeTokenDestinationReportTotalBurnedTxFees) + 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(NativeTokenDestinationReportTotalBurnedTxFees) + 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 *NativeTokenDestinationReportTotalBurnedTxFeesIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenDestinationReportTotalBurnedTxFeesIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenDestinationReportTotalBurnedTxFees represents a ReportTotalBurnedTxFees event raised by the NativeTokenDestination contract. +type NativeTokenDestinationReportTotalBurnedTxFees struct { + TeleporterMessageID *big.Int + BurnAddressBalance *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterReportTotalBurnedTxFees is a free log retrieval operation binding the contract event 0x2550fa6041684d40e635e29e93dde9017d70c25b46aa88393317b5182ed6ae7c. +// +// Solidity: event ReportTotalBurnedTxFees(uint256 indexed teleporterMessageID, uint256 burnAddressBalance) +func (_NativeTokenDestination *NativeTokenDestinationFilterer) FilterReportTotalBurnedTxFees(opts *bind.FilterOpts, teleporterMessageID []*big.Int) (*NativeTokenDestinationReportTotalBurnedTxFeesIterator, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenDestination.contract.FilterLogs(opts, "ReportTotalBurnedTxFees", teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &NativeTokenDestinationReportTotalBurnedTxFeesIterator{contract: _NativeTokenDestination.contract, event: "ReportTotalBurnedTxFees", logs: logs, sub: sub}, nil +} + +// WatchReportTotalBurnedTxFees is a free log subscription operation binding the contract event 0x2550fa6041684d40e635e29e93dde9017d70c25b46aa88393317b5182ed6ae7c. +// +// Solidity: event ReportTotalBurnedTxFees(uint256 indexed teleporterMessageID, uint256 burnAddressBalance) +func (_NativeTokenDestination *NativeTokenDestinationFilterer) WatchReportTotalBurnedTxFees(opts *bind.WatchOpts, sink chan<- *NativeTokenDestinationReportTotalBurnedTxFees, teleporterMessageID []*big.Int) (event.Subscription, error) { + + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenDestination.contract.WatchLogs(opts, "ReportTotalBurnedTxFees", teleporterMessageIDRule) + 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(NativeTokenDestinationReportTotalBurnedTxFees) + if err := _NativeTokenDestination.contract.UnpackLog(event, "ReportTotalBurnedTxFees", 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 +} + +// ParseReportTotalBurnedTxFees is a log parse operation binding the contract event 0x2550fa6041684d40e635e29e93dde9017d70c25b46aa88393317b5182ed6ae7c. +// +// Solidity: event ReportTotalBurnedTxFees(uint256 indexed teleporterMessageID, uint256 burnAddressBalance) +func (_NativeTokenDestination *NativeTokenDestinationFilterer) ParseReportTotalBurnedTxFees(log types.Log) (*NativeTokenDestinationReportTotalBurnedTxFees, error) { + event := new(NativeTokenDestinationReportTotalBurnedTxFees) + if err := _NativeTokenDestination.contract.UnpackLog(event, "ReportTotalBurnedTxFees", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenDestinationTransferToSourceIterator is returned from FilterTransferToSource and is used to iterate over the raw logs and unpacked data for TransferToSource events raised by the NativeTokenDestination contract. +type NativeTokenDestinationTransferToSourceIterator struct { + Event *NativeTokenDestinationTransferToSource // 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 interfaces.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 *NativeTokenDestinationTransferToSourceIterator) 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(NativeTokenDestinationTransferToSource) + 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(NativeTokenDestinationTransferToSource) + 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 *NativeTokenDestinationTransferToSourceIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenDestinationTransferToSourceIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenDestinationTransferToSource represents a TransferToSource event raised by the NativeTokenDestination contract. +type NativeTokenDestinationTransferToSource struct { + Sender common.Address + Recipient common.Address + TeleporterMessageID *big.Int + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransferToSource is a free log retrieval operation binding the contract event 0x0322cbb1d3c23f6dbf1deddb3b4ef3ce0f93ae6eec7b44e4f395804104466d14. +// +// Solidity: event TransferToSource(address indexed sender, address indexed recipient, uint256 indexed teleporterMessageID, uint256 amount) +func (_NativeTokenDestination *NativeTokenDestinationFilterer) FilterTransferToSource(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address, teleporterMessageID []*big.Int) (*NativeTokenDestinationTransferToSourceIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenDestination.contract.FilterLogs(opts, "TransferToSource", senderRule, recipientRule, teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &NativeTokenDestinationTransferToSourceIterator{contract: _NativeTokenDestination.contract, event: "TransferToSource", logs: logs, sub: sub}, nil +} + +// WatchTransferToSource is a free log subscription operation binding the contract event 0x0322cbb1d3c23f6dbf1deddb3b4ef3ce0f93ae6eec7b44e4f395804104466d14. +// +// Solidity: event TransferToSource(address indexed sender, address indexed recipient, uint256 indexed teleporterMessageID, uint256 amount) +func (_NativeTokenDestination *NativeTokenDestinationFilterer) WatchTransferToSource(opts *bind.WatchOpts, sink chan<- *NativeTokenDestinationTransferToSource, sender []common.Address, recipient []common.Address, teleporterMessageID []*big.Int) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenDestination.contract.WatchLogs(opts, "TransferToSource", senderRule, recipientRule, teleporterMessageIDRule) + 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(NativeTokenDestinationTransferToSource) + if err := _NativeTokenDestination.contract.UnpackLog(event, "TransferToSource", 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 +} + +// ParseTransferToSource is a log parse operation binding the contract event 0x0322cbb1d3c23f6dbf1deddb3b4ef3ce0f93ae6eec7b44e4f395804104466d14. +// +// Solidity: event TransferToSource(address indexed sender, address indexed recipient, uint256 indexed teleporterMessageID, uint256 amount) +func (_NativeTokenDestination *NativeTokenDestinationFilterer) ParseTransferToSource(log types.Log) (*NativeTokenDestinationTransferToSource, error) { + event := new(NativeTokenDestinationTransferToSource) + if err := _NativeTokenDestination.contract.UnpackLog(event, "TransferToSource", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/CrossChainApplications/NativeTokenBridge/NativeTokenSource/NativeTokenSource.go b/abi-bindings/go/CrossChainApplications/NativeTokenBridge/NativeTokenSource/NativeTokenSource.go new file mode 100644 index 000000000..6a481c666 --- /dev/null +++ b/abi-bindings/go/CrossChainApplications/NativeTokenBridge/NativeTokenSource/NativeTokenSource.go @@ -0,0 +1,869 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package nativetokensource + +import ( + "errors" + "math/big" + "strings" + + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = interfaces.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// TeleporterFeeInfo is an auto generated low-level Go binding around an user-defined struct. +type TeleporterFeeInfo struct { + FeeTokenAddress common.Address + Amount *big.Int +} + +// NativeTokenSourceMetaData contains all meta data concerning the NativeTokenSource contract. +var NativeTokenSourceMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"teleporterMessengerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"destinationBlockchainID_\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"nativeTokenDestinationAddress_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"BurnTokens\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"teleporterMessageID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TransferToDestination\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"UnlockTokens\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BURNED_TX_FEES_ADDRESS\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINT_NATIVE_TOKENS_REQUIRED_GAS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"destinationBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"destinationBurnedTotal\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nativeTokenDestinationAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"senderBlockchainID\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"senderAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"receiveTeleporterMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"teleporterMessenger\",\"outputs\":[{\"internalType\":\"contractITeleporterMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"feeTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structTeleporterFeeInfo\",\"name\":\"feeInfo\",\"type\":\"tuple\"},{\"internalType\":\"address[]\",\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\"}],\"name\":\"transferToDestination\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b506040516200173a3803806200173a8339810160408190526200003491620002b3565b60016000556001600160a01b038316620000bb5760405162461bcd60e51b815260206004820152603360248201527f4e6174697665546f6b656e536f757263653a207a65726f2054656c65706f727460448201527f65724d657373656e67657220616464726573730000000000000000000000000060648201526084015b60405180910390fd5b6001600160a01b03831660c05281620001205760405162461bcd60e51b815260206004820152603160248201526000805160206200171a8339815191526044820152701a5bdb88189b1bd8dad8da185a5b881251607a1b6064820152608401620000b2565b7302000000000000000000000000000000000000056001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000173573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001999190620002f4565b82036200020f5760405162461bcd60e51b815260206004820152603560248201527f4e6174697665546f6b656e536f757263653a2063616e6e6f742062726964676560448201527f20776974682073616d6520626c6f636b636861696e00000000000000000000006064820152608401620000b2565b60808290526001600160a01b038116620002815760405162461bcd60e51b815260206004820152603460248201526000805160206200171a83398151915260448201527f696f6e20636f6e747261637420616464726573730000000000000000000000006064820152608401620000b2565b6001600160a01b031660a052506200030e9050565b80516001600160a01b0381168114620002ae57600080fd5b919050565b600080600060608486031215620002c957600080fd5b620002d48462000296565b925060208401519150620002eb6040850162000296565b90509250925092565b6000602082840312156200030757600080fd5b5051919050565b60805160a05160c0516113ad6200036d6000396000818160ef015281816102320152818161025b015261044e015260008181610167015281816102bb015261056701526000818160920152818161029501526104e301526113ad6000f3fe60806040526004361061007b5760003560e01c8063b6171f731161004e578063b6171f731461013e578063b8c9091a14610155578063c452165e14610189578063c868efaa146101a157600080fd5b806341d3014d1461008057806355db3e9e146100c75780639b3e5803146100dd578063ad0aee2514610129575b600080fd5b34801561008c57600080fd5b506100b47f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b3480156100d357600080fd5b506100b460015481565b3480156100e957600080fd5b506101117f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100be565b61013c610137366004610eaa565b6101c1565b005b34801561014a57600080fd5b506100b4620186a081565b34801561016157600080fd5b506101117f000000000000000000000000000000000000000000000000000000000000000081565b34801561019557600080fd5b50610111600160981b81565b3480156101ad57600080fd5b5061013c6101bc366004610f49565b61043b565b6101c96106ec565b6001600160a01b0384166101f85760405162461bcd60e51b81526004016101ef90610fc3565b60405180910390fd5b60006020840135156102575761021e610214602086018661100c565b8560200135610745565b9050610257610230602086018661100c565b7f0000000000000000000000000000000000000000000000000000000000000000836108af565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663624488506040518060c001604052807f000000000000000000000000000000000000000000000000000000000000000081526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602001888036038101906102f99190611077565b8152602001620186a08152602001878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250505090825250604051602091820191610368918c913491016001600160a01b03929092168252602082015260400190565b6040516020818303038152906040528152506040518263ffffffff1660e01b81526004016103969190611163565b6020604051808303816000875af11580156103b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d991906111e1565b905080866001600160a01b0316336001600160a01b03167f2b4e8f08417773e367064a6aea9ca2df303a60876676f70b6c3c5e66b314ca5a3460405161042191815260200190565b60405180910390a450506104356001600055565b50505050565b6104436106ec565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104e15760405162461bcd60e51b815260206004820152603c60248201527f4e6174697665546f6b656e536f757263653a20756e617574686f72697a65642060448201527f54656c65706f727465724d657373656e67657220636f6e74726163740000000060648201526084016101ef565b7f000000000000000000000000000000000000000000000000000000000000000084146105655760405162461bcd60e51b815260206004820152602c60248201527f4e6174697665546f6b656e536f757263653a20696e76616c696420646573746960448201526b3730ba34b7b71031b430b4b760a11b60648201526084016101ef565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316146105f55760405162461bcd60e51b815260206004820152602660248201527f4e6174697665546f6b656e536f757263653a20756e617574686f72697a65642060448201526539b2b73232b960d11b60648201526084016101ef565b600080610604838501856111fa565b9092509050600082600181111561061d5761061d6112a6565b0361064e576000808280602001905181019061063991906112bc565b915091506106478282610994565b50506106e0565b6001826001811115610662576106626112a6565b0361068e5760008180602001905181019061067d91906111e1565b905061068881610a6d565b506106e0565b60405162461bcd60e51b815260206004820152602160248201527f4e6174697665546f6b656e536f757263653a20696e76616c696420616374696f6044820152603760f91b60648201526084016101ef565b50506104356001600055565b60026000540361073e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016101ef565b6002600055565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa15801561078e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b291906111e1565b90506107c96001600160a01b038516333086610a9c565b6040516370a0823160e01b81523060048201526000906001600160a01b038616906370a0823190602401602060405180830381865afa158015610810573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083491906111e1565b905081811161089a5760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b60648201526084016101ef565b6108a48282611300565b925050505b92915050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015610900573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092491906111e1565b61092e9190611313565b6040516001600160a01b03851660248201526044810182905290915061043590859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610ad4565b6001600160a01b0382166109ba5760405162461bcd60e51b81526004016101ef90610fc3565b80471015610a1d5760405162461bcd60e51b815260206004820152602a60248201527f4e6174697665546f6b656e536f757263653a20696e73756666696369656e742060448201526918dbdb1b185d195c985b60b21b60648201526084016101ef565b604080516001600160a01b0384168152602081018390527f55aaef8fd8c07238c3618a93c8a1627194187d3b0952908e58f2ab0f944fb407910160405180910390a1610a698282610bab565b5050565b600154811115610a9957600060015482610a879190611300565b9050610a9281610cc4565b5060018190555b50565b6040516001600160a01b03808516602483015283166044820152606481018290526104359085906323b872dd60e01b9060840161095d565b6000610b29826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610d059092919063ffffffff16565b805190915015610ba65780806020019051810190610b479190611326565b610ba65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016101ef565b505050565b80471015610bfb5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016101ef565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114610c48576040519150601f19603f3d011682016040523d82523d6000602084013e610c4d565b606091505b5050905080610ba65760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016101ef565b6040518181527f2cd3fd70cd5a5d6d805e90d22741aa1a84590ace7cf01b244719558d266143829060200160405180910390a1610a99600160981b82610bab565b6060610d148484600085610d1c565b949350505050565b606082471015610d7d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016101ef565b600080866001600160a01b03168587604051610d999190611348565b60006040518083038185875af1925050503d8060008114610dd6576040519150601f19603f3d011682016040523d82523d6000602084013e610ddb565b606091505b5091509150610dec87838387610df7565b979650505050505050565b60608315610e66578251600003610e5f576001600160a01b0385163b610e5f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101ef565b5081610d14565b610d148383815115610e7b5781518083602001fd5b8060405162461bcd60e51b81526004016101ef9190611364565b6001600160a01b0381168114610a9957600080fd5b6000806000808486036080811215610ec157600080fd5b8535610ecc81610e95565b94506040601f1982011215610ee057600080fd5b50602085019250606085013567ffffffffffffffff80821115610f0257600080fd5b818701915087601f830112610f1657600080fd5b813581811115610f2557600080fd5b8860208260051b8501011115610f3a57600080fd5b95989497505060200194505050565b60008060008060608587031215610f5f57600080fd5b843593506020850135610f7181610e95565b9250604085013567ffffffffffffffff80821115610f8e57600080fd5b818701915087601f830112610fa257600080fd5b813581811115610fb157600080fd5b886020828501011115610f3a57600080fd5b60208082526029908201527f4e6174697665546f6b656e536f757263653a207a65726f20726563697069656e60408201526874206164647265737360b81b606082015260800190565b60006020828403121561101e57600080fd5b813561102981610e95565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561106f5761106f611030565b604052919050565b60006040828403121561108957600080fd5b6040516040810181811067ffffffffffffffff821117156110ac576110ac611030565b60405282356110ba81610e95565b81526020928301359281019290925250919050565b600081518084526020808501945080840160005b838110156111085781516001600160a01b0316875295820195908201906001016110e3565b509495945050505050565b60005b8381101561112e578181015183820152602001611116565b50506000910152565b6000815180845261114f816020860160208601611113565b601f01601f19169290920160200192915050565b60208152815160208201526000602083015160018060a01b03808216604085015260408501519150808251166060850152506020810151608084015250606083015160a0830152608083015160e060c08401526111c46101008401826110cf565b905060a0840151601f198483030160e08501526108a48282611137565b6000602082840312156111f357600080fd5b5051919050565b6000806040838503121561120d57600080fd5b82356002811061121c57600080fd5b915060208381013567ffffffffffffffff8082111561123a57600080fd5b818601915086601f83011261124e57600080fd5b81358181111561126057611260611030565b611272601f8201601f19168501611046565b9150808252878482850101111561128857600080fd5b80848401858401376000848284010152508093505050509250929050565b634e487b7160e01b600052602160045260246000fd5b600080604083850312156112cf57600080fd5b82516112da81610e95565b6020939093015192949293505050565b634e487b7160e01b600052601160045260246000fd5b818103818111156108a9576108a96112ea565b808201808211156108a9576108a96112ea565b60006020828403121561133857600080fd5b8151801515811461102957600080fd5b6000825161135a818460208701611113565b9190910192915050565b602081526000611029602083018461113756fea2646970667358221220f70e4662c2679fb4a73f670c09d6430821f46cf73e7d1213af9e4e3ec525091f64736f6c634300081200334e6174697665546f6b656e536f757263653a207a65726f2064657374696e6174", +} + +// NativeTokenSourceABI is the input ABI used to generate the binding from. +// Deprecated: Use NativeTokenSourceMetaData.ABI instead. +var NativeTokenSourceABI = NativeTokenSourceMetaData.ABI + +// NativeTokenSourceBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use NativeTokenSourceMetaData.Bin instead. +var NativeTokenSourceBin = NativeTokenSourceMetaData.Bin + +// DeployNativeTokenSource deploys a new Ethereum contract, binding an instance of NativeTokenSource to it. +func DeployNativeTokenSource(auth *bind.TransactOpts, backend bind.ContractBackend, teleporterMessengerAddress common.Address, destinationBlockchainID_ [32]byte, nativeTokenDestinationAddress_ common.Address) (common.Address, *types.Transaction, *NativeTokenSource, error) { + parsed, err := NativeTokenSourceMetaData.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(NativeTokenSourceBin), backend, teleporterMessengerAddress, destinationBlockchainID_, nativeTokenDestinationAddress_) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &NativeTokenSource{NativeTokenSourceCaller: NativeTokenSourceCaller{contract: contract}, NativeTokenSourceTransactor: NativeTokenSourceTransactor{contract: contract}, NativeTokenSourceFilterer: NativeTokenSourceFilterer{contract: contract}}, nil +} + +// NativeTokenSource is an auto generated Go binding around an Ethereum contract. +type NativeTokenSource struct { + NativeTokenSourceCaller // Read-only binding to the contract + NativeTokenSourceTransactor // Write-only binding to the contract + NativeTokenSourceFilterer // Log filterer for contract events +} + +// NativeTokenSourceCaller is an auto generated read-only Go binding around an Ethereum contract. +type NativeTokenSourceCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenSourceTransactor is an auto generated write-only Go binding around an Ethereum contract. +type NativeTokenSourceTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenSourceFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type NativeTokenSourceFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenSourceSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type NativeTokenSourceSession struct { + Contract *NativeTokenSource // 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 +} + +// NativeTokenSourceCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type NativeTokenSourceCallerSession struct { + Contract *NativeTokenSourceCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// NativeTokenSourceTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type NativeTokenSourceTransactorSession struct { + Contract *NativeTokenSourceTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenSourceRaw is an auto generated low-level Go binding around an Ethereum contract. +type NativeTokenSourceRaw struct { + Contract *NativeTokenSource // Generic contract binding to access the raw methods on +} + +// NativeTokenSourceCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type NativeTokenSourceCallerRaw struct { + Contract *NativeTokenSourceCaller // Generic read-only contract binding to access the raw methods on +} + +// NativeTokenSourceTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type NativeTokenSourceTransactorRaw struct { + Contract *NativeTokenSourceTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewNativeTokenSource creates a new instance of NativeTokenSource, bound to a specific deployed contract. +func NewNativeTokenSource(address common.Address, backend bind.ContractBackend) (*NativeTokenSource, error) { + contract, err := bindNativeTokenSource(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &NativeTokenSource{NativeTokenSourceCaller: NativeTokenSourceCaller{contract: contract}, NativeTokenSourceTransactor: NativeTokenSourceTransactor{contract: contract}, NativeTokenSourceFilterer: NativeTokenSourceFilterer{contract: contract}}, nil +} + +// NewNativeTokenSourceCaller creates a new read-only instance of NativeTokenSource, bound to a specific deployed contract. +func NewNativeTokenSourceCaller(address common.Address, caller bind.ContractCaller) (*NativeTokenSourceCaller, error) { + contract, err := bindNativeTokenSource(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NativeTokenSourceCaller{contract: contract}, nil +} + +// NewNativeTokenSourceTransactor creates a new write-only instance of NativeTokenSource, bound to a specific deployed contract. +func NewNativeTokenSourceTransactor(address common.Address, transactor bind.ContractTransactor) (*NativeTokenSourceTransactor, error) { + contract, err := bindNativeTokenSource(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NativeTokenSourceTransactor{contract: contract}, nil +} + +// NewNativeTokenSourceFilterer creates a new log filterer instance of NativeTokenSource, bound to a specific deployed contract. +func NewNativeTokenSourceFilterer(address common.Address, filterer bind.ContractFilterer) (*NativeTokenSourceFilterer, error) { + contract, err := bindNativeTokenSource(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NativeTokenSourceFilterer{contract: contract}, nil +} + +// bindNativeTokenSource binds a generic wrapper to an already deployed contract. +func bindNativeTokenSource(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := NativeTokenSourceMetaData.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 (_NativeTokenSource *NativeTokenSourceRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenSource.Contract.NativeTokenSourceCaller.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 (_NativeTokenSource *NativeTokenSourceRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenSource.Contract.NativeTokenSourceTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenSource *NativeTokenSourceRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenSource.Contract.NativeTokenSourceTransactor.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 (_NativeTokenSource *NativeTokenSourceCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenSource.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 (_NativeTokenSource *NativeTokenSourceTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenSource.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenSource *NativeTokenSourceTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenSource.Contract.contract.Transact(opts, method, params...) +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_NativeTokenSource *NativeTokenSourceCaller) BURNEDTXFEESADDRESS(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenSource.contract.Call(opts, &out, "BURNED_TX_FEES_ADDRESS") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_NativeTokenSource *NativeTokenSourceSession) BURNEDTXFEESADDRESS() (common.Address, error) { + return _NativeTokenSource.Contract.BURNEDTXFEESADDRESS(&_NativeTokenSource.CallOpts) +} + +// BURNEDTXFEESADDRESS is a free data retrieval call binding the contract method 0xc452165e. +// +// Solidity: function BURNED_TX_FEES_ADDRESS() view returns(address) +func (_NativeTokenSource *NativeTokenSourceCallerSession) BURNEDTXFEESADDRESS() (common.Address, error) { + return _NativeTokenSource.Contract.BURNEDTXFEESADDRESS(&_NativeTokenSource.CallOpts) +} + +// MINTNATIVETOKENSREQUIREDGAS is a free data retrieval call binding the contract method 0xb6171f73. +// +// Solidity: function MINT_NATIVE_TOKENS_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenSource *NativeTokenSourceCaller) MINTNATIVETOKENSREQUIREDGAS(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenSource.contract.Call(opts, &out, "MINT_NATIVE_TOKENS_REQUIRED_GAS") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MINTNATIVETOKENSREQUIREDGAS is a free data retrieval call binding the contract method 0xb6171f73. +// +// Solidity: function MINT_NATIVE_TOKENS_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenSource *NativeTokenSourceSession) MINTNATIVETOKENSREQUIREDGAS() (*big.Int, error) { + return _NativeTokenSource.Contract.MINTNATIVETOKENSREQUIREDGAS(&_NativeTokenSource.CallOpts) +} + +// MINTNATIVETOKENSREQUIREDGAS is a free data retrieval call binding the contract method 0xb6171f73. +// +// Solidity: function MINT_NATIVE_TOKENS_REQUIRED_GAS() view returns(uint256) +func (_NativeTokenSource *NativeTokenSourceCallerSession) MINTNATIVETOKENSREQUIREDGAS() (*big.Int, error) { + return _NativeTokenSource.Contract.MINTNATIVETOKENSREQUIREDGAS(&_NativeTokenSource.CallOpts) +} + +// DestinationBlockchainID is a free data retrieval call binding the contract method 0x41d3014d. +// +// Solidity: function destinationBlockchainID() view returns(bytes32) +func (_NativeTokenSource *NativeTokenSourceCaller) DestinationBlockchainID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenSource.contract.Call(opts, &out, "destinationBlockchainID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// DestinationBlockchainID is a free data retrieval call binding the contract method 0x41d3014d. +// +// Solidity: function destinationBlockchainID() view returns(bytes32) +func (_NativeTokenSource *NativeTokenSourceSession) DestinationBlockchainID() ([32]byte, error) { + return _NativeTokenSource.Contract.DestinationBlockchainID(&_NativeTokenSource.CallOpts) +} + +// DestinationBlockchainID is a free data retrieval call binding the contract method 0x41d3014d. +// +// Solidity: function destinationBlockchainID() view returns(bytes32) +func (_NativeTokenSource *NativeTokenSourceCallerSession) DestinationBlockchainID() ([32]byte, error) { + return _NativeTokenSource.Contract.DestinationBlockchainID(&_NativeTokenSource.CallOpts) +} + +// DestinationBurnedTotal is a free data retrieval call binding the contract method 0x55db3e9e. +// +// Solidity: function destinationBurnedTotal() view returns(uint256) +func (_NativeTokenSource *NativeTokenSourceCaller) DestinationBurnedTotal(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _NativeTokenSource.contract.Call(opts, &out, "destinationBurnedTotal") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// DestinationBurnedTotal is a free data retrieval call binding the contract method 0x55db3e9e. +// +// Solidity: function destinationBurnedTotal() view returns(uint256) +func (_NativeTokenSource *NativeTokenSourceSession) DestinationBurnedTotal() (*big.Int, error) { + return _NativeTokenSource.Contract.DestinationBurnedTotal(&_NativeTokenSource.CallOpts) +} + +// DestinationBurnedTotal is a free data retrieval call binding the contract method 0x55db3e9e. +// +// Solidity: function destinationBurnedTotal() view returns(uint256) +func (_NativeTokenSource *NativeTokenSourceCallerSession) DestinationBurnedTotal() (*big.Int, error) { + return _NativeTokenSource.Contract.DestinationBurnedTotal(&_NativeTokenSource.CallOpts) +} + +// NativeTokenDestinationAddress is a free data retrieval call binding the contract method 0xb8c9091a. +// +// Solidity: function nativeTokenDestinationAddress() view returns(address) +func (_NativeTokenSource *NativeTokenSourceCaller) NativeTokenDestinationAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenSource.contract.Call(opts, &out, "nativeTokenDestinationAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// NativeTokenDestinationAddress is a free data retrieval call binding the contract method 0xb8c9091a. +// +// Solidity: function nativeTokenDestinationAddress() view returns(address) +func (_NativeTokenSource *NativeTokenSourceSession) NativeTokenDestinationAddress() (common.Address, error) { + return _NativeTokenSource.Contract.NativeTokenDestinationAddress(&_NativeTokenSource.CallOpts) +} + +// NativeTokenDestinationAddress is a free data retrieval call binding the contract method 0xb8c9091a. +// +// Solidity: function nativeTokenDestinationAddress() view returns(address) +func (_NativeTokenSource *NativeTokenSourceCallerSession) NativeTokenDestinationAddress() (common.Address, error) { + return _NativeTokenSource.Contract.NativeTokenDestinationAddress(&_NativeTokenSource.CallOpts) +} + +// TeleporterMessenger is a free data retrieval call binding the contract method 0x9b3e5803. +// +// Solidity: function teleporterMessenger() view returns(address) +func (_NativeTokenSource *NativeTokenSourceCaller) TeleporterMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenSource.contract.Call(opts, &out, "teleporterMessenger") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// TeleporterMessenger is a free data retrieval call binding the contract method 0x9b3e5803. +// +// Solidity: function teleporterMessenger() view returns(address) +func (_NativeTokenSource *NativeTokenSourceSession) TeleporterMessenger() (common.Address, error) { + return _NativeTokenSource.Contract.TeleporterMessenger(&_NativeTokenSource.CallOpts) +} + +// TeleporterMessenger is a free data retrieval call binding the contract method 0x9b3e5803. +// +// Solidity: function teleporterMessenger() view returns(address) +func (_NativeTokenSource *NativeTokenSourceCallerSession) TeleporterMessenger() (common.Address, error) { + return _NativeTokenSource.Contract.TeleporterMessenger(&_NativeTokenSource.CallOpts) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 senderBlockchainID, address senderAddress, bytes message) returns() +func (_NativeTokenSource *NativeTokenSourceTransactor) ReceiveTeleporterMessage(opts *bind.TransactOpts, senderBlockchainID [32]byte, senderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenSource.contract.Transact(opts, "receiveTeleporterMessage", senderBlockchainID, senderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 senderBlockchainID, address senderAddress, bytes message) returns() +func (_NativeTokenSource *NativeTokenSourceSession) ReceiveTeleporterMessage(senderBlockchainID [32]byte, senderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenSource.Contract.ReceiveTeleporterMessage(&_NativeTokenSource.TransactOpts, senderBlockchainID, senderAddress, message) +} + +// ReceiveTeleporterMessage is a paid mutator transaction binding the contract method 0xc868efaa. +// +// Solidity: function receiveTeleporterMessage(bytes32 senderBlockchainID, address senderAddress, bytes message) returns() +func (_NativeTokenSource *NativeTokenSourceTransactorSession) ReceiveTeleporterMessage(senderBlockchainID [32]byte, senderAddress common.Address, message []byte) (*types.Transaction, error) { + return _NativeTokenSource.Contract.ReceiveTeleporterMessage(&_NativeTokenSource.TransactOpts, senderBlockchainID, senderAddress, message) +} + +// TransferToDestination is a paid mutator transaction binding the contract method 0xad0aee25. +// +// Solidity: function transferToDestination(address recipient, (address,uint256) feeInfo, address[] allowedRelayerAddresses) payable returns() +func (_NativeTokenSource *NativeTokenSourceTransactor) TransferToDestination(opts *bind.TransactOpts, recipient common.Address, feeInfo TeleporterFeeInfo, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _NativeTokenSource.contract.Transact(opts, "transferToDestination", recipient, feeInfo, allowedRelayerAddresses) +} + +// TransferToDestination is a paid mutator transaction binding the contract method 0xad0aee25. +// +// Solidity: function transferToDestination(address recipient, (address,uint256) feeInfo, address[] allowedRelayerAddresses) payable returns() +func (_NativeTokenSource *NativeTokenSourceSession) TransferToDestination(recipient common.Address, feeInfo TeleporterFeeInfo, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _NativeTokenSource.Contract.TransferToDestination(&_NativeTokenSource.TransactOpts, recipient, feeInfo, allowedRelayerAddresses) +} + +// TransferToDestination is a paid mutator transaction binding the contract method 0xad0aee25. +// +// Solidity: function transferToDestination(address recipient, (address,uint256) feeInfo, address[] allowedRelayerAddresses) payable returns() +func (_NativeTokenSource *NativeTokenSourceTransactorSession) TransferToDestination(recipient common.Address, feeInfo TeleporterFeeInfo, allowedRelayerAddresses []common.Address) (*types.Transaction, error) { + return _NativeTokenSource.Contract.TransferToDestination(&_NativeTokenSource.TransactOpts, recipient, feeInfo, allowedRelayerAddresses) +} + +// NativeTokenSourceBurnTokensIterator is returned from FilterBurnTokens and is used to iterate over the raw logs and unpacked data for BurnTokens events raised by the NativeTokenSource contract. +type NativeTokenSourceBurnTokensIterator struct { + Event *NativeTokenSourceBurnTokens // 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 interfaces.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 *NativeTokenSourceBurnTokensIterator) 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(NativeTokenSourceBurnTokens) + 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(NativeTokenSourceBurnTokens) + 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 *NativeTokenSourceBurnTokensIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenSourceBurnTokensIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenSourceBurnTokens represents a BurnTokens event raised by the NativeTokenSource contract. +type NativeTokenSourceBurnTokens struct { + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBurnTokens is a free log retrieval operation binding the contract event 0x2cd3fd70cd5a5d6d805e90d22741aa1a84590ace7cf01b244719558d26614382. +// +// Solidity: event BurnTokens(uint256 amount) +func (_NativeTokenSource *NativeTokenSourceFilterer) FilterBurnTokens(opts *bind.FilterOpts) (*NativeTokenSourceBurnTokensIterator, error) { + + logs, sub, err := _NativeTokenSource.contract.FilterLogs(opts, "BurnTokens") + if err != nil { + return nil, err + } + return &NativeTokenSourceBurnTokensIterator{contract: _NativeTokenSource.contract, event: "BurnTokens", logs: logs, sub: sub}, nil +} + +// WatchBurnTokens is a free log subscription operation binding the contract event 0x2cd3fd70cd5a5d6d805e90d22741aa1a84590ace7cf01b244719558d26614382. +// +// Solidity: event BurnTokens(uint256 amount) +func (_NativeTokenSource *NativeTokenSourceFilterer) WatchBurnTokens(opts *bind.WatchOpts, sink chan<- *NativeTokenSourceBurnTokens) (event.Subscription, error) { + + logs, sub, err := _NativeTokenSource.contract.WatchLogs(opts, "BurnTokens") + 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(NativeTokenSourceBurnTokens) + if err := _NativeTokenSource.contract.UnpackLog(event, "BurnTokens", 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 +} + +// ParseBurnTokens is a log parse operation binding the contract event 0x2cd3fd70cd5a5d6d805e90d22741aa1a84590ace7cf01b244719558d26614382. +// +// Solidity: event BurnTokens(uint256 amount) +func (_NativeTokenSource *NativeTokenSourceFilterer) ParseBurnTokens(log types.Log) (*NativeTokenSourceBurnTokens, error) { + event := new(NativeTokenSourceBurnTokens) + if err := _NativeTokenSource.contract.UnpackLog(event, "BurnTokens", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenSourceTransferToDestinationIterator is returned from FilterTransferToDestination and is used to iterate over the raw logs and unpacked data for TransferToDestination events raised by the NativeTokenSource contract. +type NativeTokenSourceTransferToDestinationIterator struct { + Event *NativeTokenSourceTransferToDestination // 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 interfaces.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 *NativeTokenSourceTransferToDestinationIterator) 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(NativeTokenSourceTransferToDestination) + 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(NativeTokenSourceTransferToDestination) + 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 *NativeTokenSourceTransferToDestinationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenSourceTransferToDestinationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenSourceTransferToDestination represents a TransferToDestination event raised by the NativeTokenSource contract. +type NativeTokenSourceTransferToDestination struct { + Sender common.Address + Recipient common.Address + TeleporterMessageID *big.Int + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransferToDestination is a free log retrieval operation binding the contract event 0x2b4e8f08417773e367064a6aea9ca2df303a60876676f70b6c3c5e66b314ca5a. +// +// Solidity: event TransferToDestination(address indexed sender, address indexed recipient, uint256 indexed teleporterMessageID, uint256 amount) +func (_NativeTokenSource *NativeTokenSourceFilterer) FilterTransferToDestination(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address, teleporterMessageID []*big.Int) (*NativeTokenSourceTransferToDestinationIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenSource.contract.FilterLogs(opts, "TransferToDestination", senderRule, recipientRule, teleporterMessageIDRule) + if err != nil { + return nil, err + } + return &NativeTokenSourceTransferToDestinationIterator{contract: _NativeTokenSource.contract, event: "TransferToDestination", logs: logs, sub: sub}, nil +} + +// WatchTransferToDestination is a free log subscription operation binding the contract event 0x2b4e8f08417773e367064a6aea9ca2df303a60876676f70b6c3c5e66b314ca5a. +// +// Solidity: event TransferToDestination(address indexed sender, address indexed recipient, uint256 indexed teleporterMessageID, uint256 amount) +func (_NativeTokenSource *NativeTokenSourceFilterer) WatchTransferToDestination(opts *bind.WatchOpts, sink chan<- *NativeTokenSourceTransferToDestination, sender []common.Address, recipient []common.Address, teleporterMessageID []*big.Int) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + var teleporterMessageIDRule []interface{} + for _, teleporterMessageIDItem := range teleporterMessageID { + teleporterMessageIDRule = append(teleporterMessageIDRule, teleporterMessageIDItem) + } + + logs, sub, err := _NativeTokenSource.contract.WatchLogs(opts, "TransferToDestination", senderRule, recipientRule, teleporterMessageIDRule) + 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(NativeTokenSourceTransferToDestination) + if err := _NativeTokenSource.contract.UnpackLog(event, "TransferToDestination", 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 +} + +// ParseTransferToDestination is a log parse operation binding the contract event 0x2b4e8f08417773e367064a6aea9ca2df303a60876676f70b6c3c5e66b314ca5a. +// +// Solidity: event TransferToDestination(address indexed sender, address indexed recipient, uint256 indexed teleporterMessageID, uint256 amount) +func (_NativeTokenSource *NativeTokenSourceFilterer) ParseTransferToDestination(log types.Log) (*NativeTokenSourceTransferToDestination, error) { + event := new(NativeTokenSourceTransferToDestination) + if err := _NativeTokenSource.contract.UnpackLog(event, "TransferToDestination", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenSourceUnlockTokensIterator is returned from FilterUnlockTokens and is used to iterate over the raw logs and unpacked data for UnlockTokens events raised by the NativeTokenSource contract. +type NativeTokenSourceUnlockTokensIterator struct { + Event *NativeTokenSourceUnlockTokens // 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 interfaces.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 *NativeTokenSourceUnlockTokensIterator) 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(NativeTokenSourceUnlockTokens) + 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(NativeTokenSourceUnlockTokens) + 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 *NativeTokenSourceUnlockTokensIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenSourceUnlockTokensIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenSourceUnlockTokens represents a UnlockTokens event raised by the NativeTokenSource contract. +type NativeTokenSourceUnlockTokens struct { + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnlockTokens is a free log retrieval operation binding the contract event 0x55aaef8fd8c07238c3618a93c8a1627194187d3b0952908e58f2ab0f944fb407. +// +// Solidity: event UnlockTokens(address recipient, uint256 amount) +func (_NativeTokenSource *NativeTokenSourceFilterer) FilterUnlockTokens(opts *bind.FilterOpts) (*NativeTokenSourceUnlockTokensIterator, error) { + + logs, sub, err := _NativeTokenSource.contract.FilterLogs(opts, "UnlockTokens") + if err != nil { + return nil, err + } + return &NativeTokenSourceUnlockTokensIterator{contract: _NativeTokenSource.contract, event: "UnlockTokens", logs: logs, sub: sub}, nil +} + +// WatchUnlockTokens is a free log subscription operation binding the contract event 0x55aaef8fd8c07238c3618a93c8a1627194187d3b0952908e58f2ab0f944fb407. +// +// Solidity: event UnlockTokens(address recipient, uint256 amount) +func (_NativeTokenSource *NativeTokenSourceFilterer) WatchUnlockTokens(opts *bind.WatchOpts, sink chan<- *NativeTokenSourceUnlockTokens) (event.Subscription, error) { + + logs, sub, err := _NativeTokenSource.contract.WatchLogs(opts, "UnlockTokens") + 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(NativeTokenSourceUnlockTokens) + if err := _NativeTokenSource.contract.UnpackLog(event, "UnlockTokens", 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 +} + +// ParseUnlockTokens is a log parse operation binding the contract event 0x55aaef8fd8c07238c3618a93c8a1627194187d3b0952908e58f2ab0f944fb407. +// +// Solidity: event UnlockTokens(address recipient, uint256 amount) +func (_NativeTokenSource *NativeTokenSourceFilterer) ParseUnlockTokens(log types.Log) (*NativeTokenSourceUnlockTokens, error) { + event := new(NativeTokenSourceUnlockTokens) + if err := _NativeTokenSource.contract.UnpackLog(event, "UnlockTokens", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/contracts/src/.solhint.json b/contracts/src/.solhint.json index 058eea0ac..c94c82133 100644 --- a/contracts/src/.solhint.json +++ b/contracts/src/.solhint.json @@ -21,7 +21,7 @@ "reason-string": [ "warn", { - "maxLength": 60 + "maxLength": 75 } ], "custom-errors": "off", diff --git a/contracts/src/CrossChainApplications/ERC20Bridge/ERC20Bridge.sol b/contracts/src/CrossChainApplications/ERC20Bridge/ERC20Bridge.sol index 9a2ed44d1..b581c15d2 100644 --- a/contracts/src/CrossChainApplications/ERC20Bridge/ERC20Bridge.sol +++ b/contracts/src/CrossChainApplications/ERC20Bridge/ERC20Bridge.sol @@ -203,7 +203,7 @@ contract ERC20Bridge is // For non-zero fee amounts, first transfer the fee to this contract, and then // allow the Teleporter contract to spend it. - uint256 adjustedFeeAmount = 0; + uint256 adjustedFeeAmount; if (messageFeeAmount > 0) { adjustedFeeAmount = SafeERC20TransferFrom.safeTransferFrom( IERC20(messageFeeAsset), diff --git a/contracts/src/CrossChainApplications/ExampleMessenger/ExampleCrossChainMessenger.sol b/contracts/src/CrossChainApplications/ExampleMessenger/ExampleCrossChainMessenger.sol index d459cdcb2..0d42f7c6a 100644 --- a/contracts/src/CrossChainApplications/ExampleMessenger/ExampleCrossChainMessenger.sol +++ b/contracts/src/CrossChainApplications/ExampleMessenger/ExampleCrossChainMessenger.sol @@ -88,7 +88,7 @@ contract ExampleCrossChainMessenger is .getLatestTeleporter(); // For non-zero fee amounts, first transfer the fee to this contract, and then // allow the Teleporter contract to spend it. - uint256 adjustedFeeAmount = 0; + uint256 adjustedFeeAmount; if (feeAmount > 0) { adjustedFeeAmount = SafeERC20TransferFrom.safeTransferFrom( IERC20(feeTokenAddress), diff --git a/contracts/src/CrossChainApplications/NativeTokenBridge/ERC20TokenSource.sol b/contracts/src/CrossChainApplications/NativeTokenBridge/ERC20TokenSource.sol new file mode 100644 index 000000000..0b07a7283 --- /dev/null +++ b/contracts/src/CrossChainApplications/NativeTokenBridge/ERC20TokenSource.sol @@ -0,0 +1,224 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.18; + +import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import {IWarpMessenger} from "@subnet-evm-contracts/interfaces/IWarpMessenger.sol"; +import {IERC20TokenSource} from "./IERC20TokenSource.sol"; +import {ITokenSource} from "./ITokenSource.sol"; +import {ITeleporterMessenger, TeleporterMessageInput, TeleporterFeeInfo} from "../../Teleporter/ITeleporterMessenger.sol"; +import {ITeleporterReceiver} from "../../Teleporter/ITeleporterReceiver.sol"; +import {SafeERC20TransferFrom} from "../../Teleporter/SafeERC20TransferFrom.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +contract ERC20TokenSource is + ITeleporterReceiver, + IERC20TokenSource, + ITokenSource, + ReentrancyGuard +{ + // The address where the burned transaction fees are credited. + // Defined as BLACKHOLE_ADDRESS at + // https://github.com/ava-labs/subnet-evm/blob/e23ab058d039ff9c8469c89b139d21d52c4bd283/constants/constants.go + address public constant BURNED_TX_FEES_ADDRESS = + 0x0100000000000000000000000000000000000000; + uint256 public constant MINT_NATIVE_TOKENS_REQUIRED_GAS = 100_000; + // Used to keep track of tokens burned through transactions on the destination chain. They can + // be reported to this contract to burn an equivalent number of tokens on this chain. + uint256 public destinationBurnedTotal; + bytes32 public immutable destinationBlockchainID; + address public immutable nativeTokenDestinationAddress; + address public immutable erc20ContractAddress; + + // Used for sending and receiving Teleporter messages. + ITeleporterMessenger public immutable teleporterMessenger; + + constructor( + address teleporterMessengerAddress, + bytes32 destinationBlockchainID_, + address nativeTokenDestinationAddress_, + address erc20ContractAddress_ + ) { + require( + teleporterMessengerAddress != address(0), + "ERC20TokenSource: zero TeleporterMessenger address" + ); + teleporterMessenger = ITeleporterMessenger(teleporterMessengerAddress); + + require( + destinationBlockchainID_ != bytes32(0), + "ERC20TokenSource: zero destination blockchain ID" + ); + require( + destinationBlockchainID_ != + IWarpMessenger(0x0200000000000000000000000000000000000005) + .getBlockchainID(), + "ERC20TokenSource: cannot bridge with same blockchain" + ); + destinationBlockchainID = destinationBlockchainID_; + + require( + nativeTokenDestinationAddress_ != address(0), + "ERC20TokenSource: zero destination contract address" + ); + nativeTokenDestinationAddress = nativeTokenDestinationAddress_; + + require( + erc20ContractAddress_ != address(0), + "ERC20TokenSource: zero ERC20 contract address" + ); + erc20ContractAddress = erc20ContractAddress_; + } + + /** + * @dev See {ITeleporterReceiver-receiveTeleporterMessage}. + * + * Receives a Teleporter message and routes to the appropriate internal function call. + */ + function receiveTeleporterMessage( + bytes32 senderBlockchainID, + address senderAddress, + bytes calldata message + ) external nonReentrant { + // Only allow the Teleporter messenger to deliver messages. + require( + msg.sender == address(teleporterMessenger), + "ERC20TokenSource: unauthorized TeleporterMessenger contract" + ); + + // Only allow messages from the destination chain. + require( + senderBlockchainID == destinationBlockchainID, + "ERC20TokenSource: invalid destination chain" + ); + + // Only allow the partner contract to send messages. + require( + senderAddress == nativeTokenDestinationAddress, + "ERC20TokenSource: unauthorized sender" + ); + + // Decode the payload to recover the action and corresponding function parameters + (SourceAction action, bytes memory actionData) = abi.decode( + message, + (SourceAction, bytes) + ); + + // Route to the appropriate function. + if (action == SourceAction.Unlock) { + (address recipient, uint256 amount) = abi.decode( + actionData, + (address, uint256) + ); + _unlockTokens(recipient, amount); + } else if (action == SourceAction.Burn) { + uint256 newBurnTotal = abi.decode(actionData, (uint256)); + _handleBurnTokens(newBurnTotal); + } else { + revert("ERC20TokenSource: invalid action"); + } + } + + /** + * @dev See {IERC20TokenSource-transferToDestination}. + */ + function transferToDestination( + address recipient, + uint256 totalAmount, + uint256 feeAmount, + address[] calldata allowedRelayerAddresses + ) external nonReentrant { + // The recipient cannot be the zero address. + require( + recipient != address(0), + "ERC20TokenSource: zero recipient address" + ); + + // Lock tokens in this contract. Supports "fee/burn on transfer" ERC20 token + // implementations by only bridging the actual balance increase reflected by the call + // to transferFrom. + uint256 adjustedAmount = SafeERC20TransferFrom.safeTransferFrom( + IERC20(erc20ContractAddress), + totalAmount + ); + + // Ensure that the adjusted amount is greater than the fee to be paid. + require( + adjustedAmount > feeAmount, + "ERC20TokenSource: insufficient adjusted amount" + ); + + // Allow the Teleporter messenger to spend the fee amount. + if (feeAmount > 0) { + SafeERC20.safeIncreaseAllowance( + IERC20(erc20ContractAddress), + address(teleporterMessenger), + feeAmount + ); + } + + uint256 transferAmount = adjustedAmount - feeAmount; + + uint256 messageID = teleporterMessenger.sendCrossChainMessage( + TeleporterMessageInput({ + destinationBlockchainID: destinationBlockchainID, + destinationAddress: nativeTokenDestinationAddress, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: erc20ContractAddress, + amount: feeAmount + }), + requiredGasLimit: MINT_NATIVE_TOKENS_REQUIRED_GAS, + allowedRelayerAddresses: allowedRelayerAddresses, + message: abi.encode(recipient, transferAmount) + }) + ); + + emit TransferToDestination({ + sender: msg.sender, + recipient: recipient, + amount: transferAmount, + teleporterMessageID: messageID + }); + } + + /** + * @dev Unlocks tokens to recipient. + */ + function _unlockTokens(address recipient, uint256 amount) private { + require( + recipient != address(0), + "ERC20TokenSource: zero recipient address" + ); + + // Transfer to recipient + emit UnlockTokens(recipient, amount); + SafeERC20.safeTransfer(IERC20(erc20ContractAddress), recipient, amount); + } + + /** + * @dev Sends tokens to BURNED_TX_FEES_ADDRESS. + */ + function _burnTokens(uint256 amount) private { + emit BurnTokens(amount); + SafeERC20.safeTransfer( + IERC20(erc20ContractAddress), + BURNED_TX_FEES_ADDRESS, + amount + ); + } + + /** + * @dev Update destinationBurnedTotal sent from destination chain + */ + function _handleBurnTokens(uint256 newBurnTotal) private { + if (newBurnTotal > destinationBurnedTotal) { + uint256 difference = newBurnTotal - destinationBurnedTotal; + _burnTokens(difference); + destinationBurnedTotal = newBurnTotal; + } + } +} diff --git a/contracts/src/CrossChainApplications/NativeTokenBridge/IERC20TokenSource.sol b/contracts/src/CrossChainApplications/NativeTokenBridge/IERC20TokenSource.sol new file mode 100644 index 000000000..1567c4793 --- /dev/null +++ b/contracts/src/CrossChainApplications/NativeTokenBridge/IERC20TokenSource.sol @@ -0,0 +1,23 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.18; + +/** + * @dev Interface that describes functionalities for a contract that will lock ERC20 tokens and send a + * Teleporter message to a {INativeTokenDestination} contract to mint native tokens on the destination chain. + */ +interface IERC20TokenSource { + /** + * @dev Locks ERC20 tokens on the source contract chain, and sends a message to mint the + * corresponding native tokens on the destination chain. + */ + function transferToDestination( + address recipient, + uint256 totalAmount, + uint256 feeAmount, + address[] calldata allowedRelayerAddresses + ) external; +} diff --git a/contracts/src/CrossChainApplications/NativeTokenBridge/INativeTokenDestination.sol b/contracts/src/CrossChainApplications/NativeTokenBridge/INativeTokenDestination.sol new file mode 100644 index 000000000..285711acb --- /dev/null +++ b/contracts/src/CrossChainApplications/NativeTokenBridge/INativeTokenDestination.sol @@ -0,0 +1,72 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.18; + +import {TeleporterFeeInfo} from "../../Teleporter/ITeleporterMessenger.sol"; + +/** + * @dev Interface that describes functionalities for a contract that can mint native tokens when + * paired with a {INativeTokenSource} or {IERC20TokenSource} contract that will lock tokens on another chain. + */ +interface INativeTokenDestination { + /** + * @dev Emitted when tokens are burned in the destination contract and to be unlocked on the source contract. + */ + event TransferToSource( + address indexed sender, + address indexed recipient, + uint256 indexed teleporterMessageID, + uint256 amount + ); + + /** + * @dev Emitted when tokens are not minted in order to collateralize the source contract. + */ + event CollateralAdded(uint256 amount, uint256 remaining); + + /** + * @dev Emitted when minting native tokens. + */ + event NativeTokensMinted(address indexed recipient, uint256 amount); + + /** + * @dev Emitted when reporting total burned tx fees to source chain. + */ + event ReportTotalBurnedTxFees( + uint256 indexed teleporterMessageID, + uint256 burnAddressBalance + ); + + /** + * @dev Burns native tokens on the destination contract chain, and sends a message to the source + * contract to unlock corresponding tokens. + */ + function transferToSource( + address recipient, + TeleporterFeeInfo calldata feeInfo, + address[] calldata allowedRelayerAddresses + ) external payable; + + /** + * @dev Reports the current total burned transaction fees on this chain to the source chain. + */ + function reportTotalBurnedTxFees( + TeleporterFeeInfo calldata feeInfo, + address[] calldata allowedRelayerAddresses + ) external; + + /** + * @dev Returns true if the reserve imbalance for this contract has been accounted for. + * When this is true, all tokens sent to this chain will be minted, and sending tokens + * to the source chain is allowed. + */ + function isCollateralized() external view returns (bool); + + /** + * @dev Returns a best-estimate (upper bound) of tokens in circulation on this chain. + */ + function totalSupply() external view returns (uint256); +} diff --git a/contracts/src/CrossChainApplications/NativeTokenBridge/INativeTokenSource.sol b/contracts/src/CrossChainApplications/NativeTokenBridge/INativeTokenSource.sol new file mode 100644 index 000000000..c425f7ec9 --- /dev/null +++ b/contracts/src/CrossChainApplications/NativeTokenBridge/INativeTokenSource.sol @@ -0,0 +1,24 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.18; + +import {TeleporterFeeInfo} from "../../Teleporter/ITeleporterMessenger.sol"; + +/** + * @dev Interface that describes functionalities for a contract that will lock native tokens on the source chain and send a + * Teleporter message to a {INativeTokenDestination} contract to mint native tokens on the destination chain. + */ +interface INativeTokenSource { + /** + * @dev Locks native tokens on the source contract chain, and sends a message to the destination + * contract to mint corresponding tokens. + */ + function transferToDestination( + address recipient, + TeleporterFeeInfo calldata feeInfo, + address[] calldata allowedRelayerAddresses + ) external payable; +} diff --git a/contracts/src/CrossChainApplications/NativeTokenBridge/ITokenSource.sol b/contracts/src/CrossChainApplications/NativeTokenBridge/ITokenSource.sol new file mode 100644 index 000000000..9ba712f12 --- /dev/null +++ b/contracts/src/CrossChainApplications/NativeTokenBridge/ITokenSource.sol @@ -0,0 +1,40 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.18; + +/** + * @dev Interface for common functionality needed for different `TokenSource` contracts such as + * `NativeTokenSource` and `ERC20TokenSource`. + */ +interface ITokenSource { + /** + * @dev Enum representing the action to take on receiving a Teleporter message. + */ + enum SourceAction { + Unlock, + Burn + } + + /** + * @dev Emitted when native tokens are locked in the source contract to be transferred to the destination chain. + */ + event TransferToDestination( + address indexed sender, + address indexed recipient, + uint256 indexed teleporterMessageID, + uint256 amount + ); + + /** + * @dev Emitted when tokens are unlocked on this chain. + */ + event UnlockTokens(address recipient, uint256 amount); + + /** + * @dev Emitted when tokens are burned on this chain. + */ + event BurnTokens(uint256 amount); +} \ No newline at end of file diff --git a/contracts/src/CrossChainApplications/NativeTokenBridge/NativeTokenDestination.sol b/contracts/src/CrossChainApplications/NativeTokenBridge/NativeTokenDestination.sol new file mode 100644 index 000000000..3d8648619 --- /dev/null +++ b/contracts/src/CrossChainApplications/NativeTokenBridge/NativeTokenDestination.sol @@ -0,0 +1,264 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.18; + +import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import {Address} from "@openzeppelin/contracts/utils/Address.sol"; +import {IWarpMessenger} from "@subnet-evm-contracts/interfaces/IWarpMessenger.sol"; +import {INativeMinter} from "@subnet-evm-contracts/interfaces/INativeMinter.sol"; +import {INativeTokenDestination} from "./INativeTokenDestination.sol"; +import {ITokenSource} from "./ITokenSource.sol"; +import {ITeleporterMessenger, TeleporterFeeInfo, TeleporterMessageInput} from "../../Teleporter/ITeleporterMessenger.sol"; +import {ITeleporterReceiver} from "../../Teleporter/ITeleporterReceiver.sol"; +import {SafeERC20TransferFrom} from "../../Teleporter/SafeERC20TransferFrom.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +// We need IAllowList as an indirect dependency in order to compile. +// solhint-disable-next-line no-unused-import +import {IAllowList} from "@subnet-evm-contracts/interfaces/IAllowList.sol"; + +contract NativeTokenDestination is + ITeleporterReceiver, + INativeTokenDestination, + ReentrancyGuard +{ + // The address where the burned transaction fees are credited. + // Defined as BLACKHOLE_ADDRESS at + // https://github.com/ava-labs/subnet-evm/blob/e23ab058d039ff9c8469c89b139d21d52c4bd283/constants/constants.go + address public constant BURNED_TX_FEES_ADDRESS = 0x0100000000000000000000000000000000000000; + // Designated Blackhole Address for this contract. Tokens are sent here to be "burned" before + // sending an unlock message to the source chain. Different from the burned tx fee address so + // they can be tracked separately. + address public constant BURN_FOR_TRANSFER_ADDRESS = 0x0100000000000000000000000000000000000001; + + INativeMinter private immutable _nativeMinter = + INativeMinter(0x0200000000000000000000000000000000000001); + + uint256 public constant TRANSFER_NATIVE_TOKENS_REQUIRED_GAS = 100_000; + uint256 public constant REPORT_BURNED_TOKENS_REQUIRED_GAS = 100_000; + bytes32 public immutable sourceBlockchainID; + address public immutable nativeTokenSourceAddress; + // The first `initialReserveImbalance` tokens sent to this subnet will not be minted. + // `initialReserveImbalance` should be constructed to match the initial token supply of this subnet. + // This means tokens will not be minted until the source contact is collateralized. + uint256 public immutable initialReserveImbalance; + uint256 public currentReserveImbalance; + uint256 public totalMinted; + + // Used for sending and receiving Teleporter messages. + ITeleporterMessenger public immutable teleporterMessenger; + + constructor( + address teleporterMessengerAddress, + bytes32 sourceBlockchainID_, + address nativeTokenSourceAddress_, + uint256 initialReserveImbalance_ + ) { + require( + teleporterMessengerAddress != address(0), + "NativeTokenDestination: zero TeleporterMessenger address" + ); + teleporterMessenger = ITeleporterMessenger(teleporterMessengerAddress); + + require( + sourceBlockchainID_ != bytes32(0), + "NativeTokenDestination: zero source blockchain ID" + ); + require( + sourceBlockchainID_ != + IWarpMessenger(0x0200000000000000000000000000000000000005) + .getBlockchainID(), + "NativeTokenDestination: cannot bridge with same blockchain" + ); + sourceBlockchainID = sourceBlockchainID_; + + require( + nativeTokenSourceAddress_ != address(0), + "NativeTokenDestination: zero source contract address" + ); + nativeTokenSourceAddress = nativeTokenSourceAddress_; + + require( + initialReserveImbalance_ != 0, + "NativeTokenDestination: zero initial reserve imbalance" + ); + + initialReserveImbalance = initialReserveImbalance_; + currentReserveImbalance = initialReserveImbalance_; + } + + /** + * @dev See {ITeleporterReceiver-receiveTeleporterMessage}. + * + * Receives a Teleporter message. + */ + function receiveTeleporterMessage( + bytes32 senderBlockchainID, + address senderAddress, + bytes calldata message + ) external nonReentrant { + // Only allow the Teleporter messenger to deliver messages. + require( + msg.sender == address(teleporterMessenger), + "NativeTokenDestination: unauthorized TeleporterMessenger contract" + ); + + // Only allow messages from the source chain. + require( + senderBlockchainID == sourceBlockchainID, + "NativeTokenDestination: invalid source chain" + ); + + // Only allow the partner contract to send messages. + require( + senderAddress == nativeTokenSourceAddress, + "NativeTokenDestination: unauthorized sender" + ); + + (address recipient, uint256 amount) = abi.decode( + message, + (address, uint256) + ); + require( + recipient != address(0), + "NativeTokenDestination: zero recipient address" + ); + require(amount != 0, "NativeTokenDestination: zero transfer value"); + + // If the contract has not yet been collateralized, we will deduct as many tokens + // as needed from the transfer as needed. If there are any excess tokens, they will + // be minted and sent to the recipient. + uint256 adjustedAmount = amount; + if (currentReserveImbalance > 0) { + if (amount > currentReserveImbalance) { + emit CollateralAdded({ + amount: currentReserveImbalance, + remaining: 0 + }); + adjustedAmount = amount - currentReserveImbalance; + currentReserveImbalance = 0; + } else { + currentReserveImbalance -= amount; + emit CollateralAdded({ + amount: amount, + remaining: currentReserveImbalance + }); + return; + } + } + + totalMinted += adjustedAmount; + emit NativeTokensMinted(recipient, adjustedAmount); + // Calls NativeMinter precompile through INativeMinter interface. + _nativeMinter.mintNativeCoin(recipient, adjustedAmount); + } + + /** + * @dev See {INativeTokenDestination-transferToSource}. + */ + function transferToSource( + address recipient, + TeleporterFeeInfo calldata feeInfo, + address[] calldata allowedRelayerAddresses + ) external payable nonReentrant { + // The recipient cannot be the zero address. + require( + recipient != address(0), + "NativeTokenDestination: zero recipient address" + ); + + require( + currentReserveImbalance == 0, + "NativeTokenDestination: contract undercollateralized" + ); + + // Lock tokens in this bridge instance. Supports "fee/burn on transfer" ERC20 token + // implementations by only bridging the actual balance increase reflected by the call + // to transferFrom. + uint256 adjustedFeeAmount; + if (feeInfo.amount > 0) { + adjustedFeeAmount = SafeERC20TransferFrom.safeTransferFrom( + IERC20(feeInfo.feeTokenAddress), + feeInfo.amount + ); + SafeERC20.safeIncreaseAllowance( + IERC20(feeInfo.feeTokenAddress), + address(teleporterMessenger), + adjustedFeeAmount + ); + } + + // Burn native token by sending to BURN_FOR_TRANSFER_ADDRESS + Address.sendValue(payable(BURN_FOR_TRANSFER_ADDRESS), msg.value); + + uint256 messageID = teleporterMessenger.sendCrossChainMessage( + TeleporterMessageInput({ + destinationBlockchainID: sourceBlockchainID, + destinationAddress: nativeTokenSourceAddress, + feeInfo: feeInfo, + requiredGasLimit: TRANSFER_NATIVE_TOKENS_REQUIRED_GAS, + allowedRelayerAddresses: allowedRelayerAddresses, + message: abi.encode( + ITokenSource.SourceAction.Unlock, + abi.encode(recipient, msg.value) + ) + }) + ); + + emit TransferToSource({ + sender: msg.sender, + recipient: recipient, + amount: msg.value, + teleporterMessageID: messageID + }); + } + + /** + * @dev See {INativeTokenDestination-reportTotalBurnedTxFees}. + */ + function reportTotalBurnedTxFees( + TeleporterFeeInfo calldata feeInfo, + address[] calldata allowedRelayerAddresses + ) external { + uint256 totalBurnedTxFees = address(BURNED_TX_FEES_ADDRESS).balance; + uint256 messageID = teleporterMessenger.sendCrossChainMessage( + TeleporterMessageInput({ + destinationBlockchainID: sourceBlockchainID, + destinationAddress: nativeTokenSourceAddress, + feeInfo: feeInfo, + requiredGasLimit: REPORT_BURNED_TOKENS_REQUIRED_GAS, + allowedRelayerAddresses: allowedRelayerAddresses, + message: abi.encode( + ITokenSource.SourceAction.Burn, + abi.encode(totalBurnedTxFees) + ) + }) + ); + + emit ReportTotalBurnedTxFees({ + burnAddressBalance: totalBurnedTxFees, + teleporterMessageID: messageID + }); + } + + /** + * @dev See {INativeTokenDestination-isCollateralized}. + */ + function isCollateralized() external view returns (bool) { + return currentReserveImbalance == 0; + } + + /** + * @dev See {INativeTokenDestination-totalSupply}. + */ + function totalSupply() external view returns (uint256) { + uint256 burned = address(BURNED_TX_FEES_ADDRESS).balance + + address(BURN_FOR_TRANSFER_ADDRESS).balance; + uint256 created = totalMinted + initialReserveImbalance; + + return created - burned; + } +} diff --git a/contracts/src/CrossChainApplications/NativeTokenBridge/NativeTokenSource.sol b/contracts/src/CrossChainApplications/NativeTokenBridge/NativeTokenSource.sol new file mode 100644 index 000000000..75a238518 --- /dev/null +++ b/contracts/src/CrossChainApplications/NativeTokenBridge/NativeTokenSource.sol @@ -0,0 +1,208 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.18; + +import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import {Address} from "@openzeppelin/contracts/utils/Address.sol"; +import {IWarpMessenger} from "@subnet-evm-contracts/interfaces/IWarpMessenger.sol"; +import {INativeTokenSource} from "./INativeTokenSource.sol"; +import {ITokenSource} from "./ITokenSource.sol"; +import {ITeleporterMessenger, TeleporterFeeInfo, TeleporterMessageInput} from "../../Teleporter/ITeleporterMessenger.sol"; +import {ITeleporterReceiver} from "../../Teleporter/ITeleporterReceiver.sol"; +import {SafeERC20TransferFrom} from "../../Teleporter/SafeERC20TransferFrom.sol"; +import {SafeERC20TransferFrom} from "../../Teleporter/SafeERC20TransferFrom.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +contract NativeTokenSource is + ITeleporterReceiver, + INativeTokenSource, + ITokenSource, + ReentrancyGuard +{ + // The address where the burned transaction fees are credited. + // Defined as BLACKHOLE_ADDRESS at + // https://github.com/ava-labs/subnet-evm/blob/e23ab058d039ff9c8469c89b139d21d52c4bd283/constants/constants.go + address public constant BURNED_TX_FEES_ADDRESS = + 0x0100000000000000000000000000000000000000; + uint256 public constant MINT_NATIVE_TOKENS_REQUIRED_GAS = 100_000; + // Used to keep track of tokens burned through transactions on the destination chain. They can + // be reported to this contract to burn an equivalent number of tokens on this chain. + uint256 public destinationBurnedTotal; + bytes32 public immutable destinationBlockchainID; + address public immutable nativeTokenDestinationAddress; + + // Used for sending and receiving Teleporter messages. + ITeleporterMessenger public immutable teleporterMessenger; + + constructor( + address teleporterMessengerAddress, + bytes32 destinationBlockchainID_, + address nativeTokenDestinationAddress_ + ) { + require( + teleporterMessengerAddress != address(0), + "NativeTokenSource: zero TeleporterMessenger address" + ); + teleporterMessenger = ITeleporterMessenger(teleporterMessengerAddress); + + require( + destinationBlockchainID_ != bytes32(0), + "NativeTokenSource: zero destination blockchain ID" + ); + require( + destinationBlockchainID_ != + IWarpMessenger(0x0200000000000000000000000000000000000005) + .getBlockchainID(), + "NativeTokenSource: cannot bridge with same blockchain" + ); + destinationBlockchainID = destinationBlockchainID_; + + require( + nativeTokenDestinationAddress_ != address(0), + "NativeTokenSource: zero destination contract address" + ); + nativeTokenDestinationAddress = nativeTokenDestinationAddress_; + } + + /** + * @dev See {ITeleporterReceiver-receiveTeleporterMessage}. + * + * Receives a Teleporter message and routes to the appropriate internal function call. + */ + function receiveTeleporterMessage( + bytes32 senderBlockchainID, + address senderAddress, + bytes calldata message + ) external nonReentrant { + // Only allow the Teleporter messenger to deliver messages. + require( + msg.sender == address(teleporterMessenger), + "NativeTokenSource: unauthorized TeleporterMessenger contract" + ); + + // Only allow messages from the destination chain. + require( + senderBlockchainID == destinationBlockchainID, + "NativeTokenSource: invalid destination chain" + ); + + // Only allow the partner contract to send messages. + require( + senderAddress == nativeTokenDestinationAddress, + "NativeTokenSource: unauthorized sender" + ); + + // Decode the payload to recover the action and corresponding function parameters + (SourceAction action, bytes memory actionData) = abi.decode( + message, + (SourceAction, bytes) + ); + + // Route to the appropriate function. + if (action == SourceAction.Unlock) { + (address recipient, uint256 amount) = abi.decode( + actionData, + (address, uint256) + ); + _unlockTokens(recipient, amount); + } else if (action == SourceAction.Burn) { + uint256 newBurnTotal = abi.decode(actionData, (uint256)); + _handleBurnTokens(newBurnTotal); + } else { + revert("NativeTokenSource: invalid action"); + } + } + + /** + * @dev See {INativeTokenSource-transferToDestination}. + */ + function transferToDestination( + address recipient, + TeleporterFeeInfo calldata feeInfo, + address[] calldata allowedRelayerAddresses + ) external payable nonReentrant { + // The recipient cannot be the zero address. + require( + recipient != address(0), + "NativeTokenSource: zero recipient address" + ); + + // Lock tokens in this bridge instance. Supports "fee/burn on transfer" ERC20 token + // implementations by only bridging the actual balance increase reflected by the call + // to transferFrom. + uint256 adjustedFeeAmount; + if (feeInfo.amount > 0) { + adjustedFeeAmount = SafeERC20TransferFrom.safeTransferFrom( + IERC20(feeInfo.feeTokenAddress), + feeInfo.amount + ); + SafeERC20.safeIncreaseAllowance( + IERC20(feeInfo.feeTokenAddress), + address(teleporterMessenger), + adjustedFeeAmount + ); + } + + uint256 messageID = teleporterMessenger.sendCrossChainMessage( + TeleporterMessageInput({ + destinationBlockchainID: destinationBlockchainID, + destinationAddress: nativeTokenDestinationAddress, + feeInfo: feeInfo, + requiredGasLimit: MINT_NATIVE_TOKENS_REQUIRED_GAS, + allowedRelayerAddresses: allowedRelayerAddresses, + message: abi.encode(recipient, msg.value) + }) + ); + + emit TransferToDestination({ + sender: msg.sender, + recipient: recipient, + amount: msg.value, + teleporterMessageID: messageID + }); + } + + /** + * @dev Unlocks tokens to recipient. + */ + function _unlockTokens(address recipient, uint256 amount) private { + require( + recipient != address(0), + "NativeTokenSource: zero recipient address" + ); + require( + address(this).balance >= amount, + "NativeTokenSource: insufficient collateral" + ); + + // Transfer to recipient + emit UnlockTokens(recipient, amount); + Address.sendValue(payable(recipient), amount); + } + + /** + * @dev Sends tokens to BURNED_TX_FEES_ADDRESS. + */ + function _burnTokens(uint256 amount) private { + emit BurnTokens(amount); + Address.sendValue(payable(BURNED_TX_FEES_ADDRESS), amount); + } + + /** + * @dev Update destinationBurnedTotal sent from destination chain + * If the new burned total is less than the highest known burned total, this transaction is a no-op. + * The burned total on the destination will only ever increase, but new totals may be relayed to this + * chain out of order. + */ + function _handleBurnTokens(uint256 newBurnTotal) private { + if (newBurnTotal > destinationBurnedTotal) { + uint256 difference = newBurnTotal - destinationBurnedTotal; + _burnTokens(difference); + destinationBurnedTotal = newBurnTotal; + } + } +} diff --git a/contracts/src/CrossChainApplications/NativeTokenBridge/README.md b/contracts/src/CrossChainApplications/NativeTokenBridge/README.md new file mode 100644 index 000000000..e497ee526 --- /dev/null +++ b/contracts/src/CrossChainApplications/NativeTokenBridge/README.md @@ -0,0 +1,45 @@ +# Native Token Bridge + +Smart contracts built on top of Teleporter to support using an ERC20 token or the native token of any EVM-based subnet as the native token for another subnet. + +## Design +The Native Token Bridge is implemented using two primary contracts. + +A `TokenSource` contract lives on the `source chain`, which can be any chain on Avalanche. + +A `NativeTokenDestination` contract lives on the `destination chain`, which should be a newly created subnet. + +### `TokenSource` +Can either be a `NativeTokenSource` contract or an `ERC20TokenSource` contract. It lives on the source chain. Pairs with exactly one `NativeTokenDestination` contract on the destination chain. It locks and unlocks native tokens on the Source chain corresponding to mints and burns on the destination chain. +- `transferToDestination`: Transfers all tokens paid to this function call to `recipient` on the destination chain by locking them and instructing the destination chain to mint. Optionally takes the address of an ERC20 contract `feeContractAddress` as well as an amount `feeAmount` that will be used as the relayer-incentivization for the teleporter cross-chain call. Also allows for the caller to specify `allowedRelayerAddresses`. +- `receiveTeleporterMessage`: Only accepts Teleporter messages from the `NativeTokenDestination` contract on the destination chain. Can receive two types of messages: + - `Unlock`: Unlocks tokens on the source chain when instructed to by the `NativeTokenDestination` contract. + - `Burn`: Burns tokens on the source chain when instructed to by a call to `reportTotalBurnedTxFees` on the `NativeTokenDestination` contract. This function will burn tokens equal to the increase from the highest previously reported total from the destination chain. + +### `NativeTokenDestination` +A contract that lives on the destination chain. Pairs with exactly one `TokenSource` contract on the source chain. It mints and burns native tokens on the Destination chain corresponding to locks and unlocks on the source chain. +- `transferToSource`: Transfers all tokens paid to this function call to `recipient` on the source chain by burning the tokens and instructing the source chain to unlock. Optionally takes the address of an ERC20 contract `feeContractAddress` as well as an amount `feeAmount` that will be used as the relayer-incentivisation for the teleporter cross-chain call. Also allows for the caller to specify `allowedRelayerAddresses`. +- `receiveTeleporterMessage`: Only accepts Teleporter messages from the `TokenSource` contract on the source chain. gMints tokens on the destination chain when instructed to by the `NativeTokenDestination` contract. +- `isCollateralized`: Returns true if `currentReserveImbalance == 0`, meaning that enough tokens have been sent from the source chain to offset the `initialReserveImbalance`. If true, all tokens sent to the destination chain will be minted, and burning/unlocking tokens will be enabled. +- `totalSupply`: Returns the best estimate of available native tokens on this chain. Equal to the `initialReserveImbalance` + `all tokens minted` - `all tokens in known burn address`. Known burn addresses include the burn address for this contract used when burning/unlocking, and the address for burned transaction fees. +- `reportTotalBurnedTxFees`: Sends a Teleporter message to the source chain containing the total number of tokens at `0x0100000000000000000000000000000000000000`. + +### `Collateralizing the bridge` +On initialization, the bridge will be undercollateralized by exactly the number of tokens minted in the genesis block on the destination chain. These tokens could theoretically be sent through the bridge, with no corresponding tokens able to be unlocked on the source chain. In order to avoid this problem, the `NativeTokenDestination` contract is initialized with the value for `initialReserveImbalance`. + +`initialReserveImbalance` should correspond to the number of tokens allocated in the genesis block of the destination chain. If `initialReserveImbalance` is not properly set, behavior of this contract is undefined. The `NativeTokenDestination` contract will not mint tokens until it at least `initialReserveImbalance` tokens have been locked on the source chain. + +It is left to the contract deployer to ensure that the bridge is properly collateralized. Burning/unlocking is disabled until the bridge is properly collateralized. + +### `Burning tokens spent as fees` +As tokens are burned for transaction fees on the destination chain, contract owners may want to relay this information to the source chain in order to burn an equivalent number of locked tokens there because these tokens will never be bridged back. + +The address for burned transaction fees is `0x0100000000000000000000000000000000000000`. When transferring token to the source chain, the "burned" tokens are sent here so that `0x0100000000000000000000000000000000000000` will only include burned transaction fees (or tokens others have decided to burn outside of this contract) so that this number can be reported to the source chain to burn an equivalent numbers of locked tokens. + +## `Setup` +- `TeleporterMessenger` must be deployed on both chains, and the address must be passed to the constructor of both contracts. +- `NativeTokenDestination` is meant to be deployed on a new subnet, and should be the only method for minting tokens on that subnet. The address of `NativeTokenDestination` must be included as the only entry for `adminAddresses` under `contractNativeMinterConfig` in the genesis config for the destination subnet. See `warp-genesis.json` for an example. +- Both the chosen `TokenSource` contract and `NativeTokenDestination` need to be deployed to addresses known beforehand. Each address must be passed to the constructor of the other contract. To do this, you will need a known EOA, and preferably use the first transaction from the EOA (nonce 0) to deploy the contract on each chain. It is advised to allocate tokens to the EOA in the destination subnet genesis file so that it can easily deploy the contract. +- Both contracts need to be initialized with `teleporterMessengerAddress`, which is the only address they will accept function calls from. +- `NativeTokenDestination` needs to be intialized with `initialReserveImbalance`, which should equal the number of tokens allocated in the genesis file for the destination chain. If `initialReserveImbalance` is not properly set, behavior of these contracts in undefined. +- On the source chain, at least `initialReserveImbalance` tokens need to be transferred to the `TokenSource` contract using `transferToSource` in order to properly collateralize the bridge and allow regular functionality in both directions. The first `initialReserveImbalance` tokens will not be delivered to the recipient, but any excess will be delivered. Burning/unlocking is disabled until the bridge is fully collateralized. \ No newline at end of file diff --git a/contracts/src/CrossChainApplications/NativeTokenBridge/tests/ERC20TokenSourceTests.t.sol b/contracts/src/CrossChainApplications/NativeTokenBridge/tests/ERC20TokenSourceTests.t.sol new file mode 100644 index 000000000..3afd106d2 --- /dev/null +++ b/contracts/src/CrossChainApplications/NativeTokenBridge/tests/ERC20TokenSourceTests.t.sol @@ -0,0 +1,362 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.18; + +import {Test} from "forge-std/Test.sol"; +import {ERC20TokenSource, IERC20, ITokenSource, TeleporterMessageInput, TeleporterFeeInfo, IWarpMessenger, ITeleporterMessenger} from "../ERC20TokenSource.sol"; +import {UnitTestMockERC20} from "../../../Mocks/UnitTestMockERC20.sol"; + +contract ERC20TokenSourceTest is Test { + address public constant MOCK_TELEPORTER_MESSENGER_ADDRESS = + 0x644E5b7c5D4Bc8073732CEa72c66e0BB90dFC00f; + address public constant WARP_PRECOMPILE_ADDRESS = + address(0x0200000000000000000000000000000000000005); + bytes32 private constant _MOCK_BLOCKCHAIN_ID = bytes32(uint256(123456)); + bytes32 private constant _DEFAULT_OTHER_CHAIN_ID = + bytes32( + hex"abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd" + ); + address private constant _DEFAULT_OTHER_BRIDGE_ADDRESS = + 0xd54e3E251b9b0EEd3ed70A858e927bbC2659587d; + uint256 private constant _DEFAULT_INITIAL_RESERVE_IMBALANCE = 1000000000; + address private constant _DEFAULT_RECIPIENT = + 0xa4CEE7d1aF6aDdDD33E3b1cC680AB84fdf1b6d1d; + uint256 private constant _DEFAULT_TRANSFER_AMOUNT = 1e18; + uint256 private constant _DEFAULT_FEE_AMOUNT = 123456; + + ERC20TokenSource public erc20TokenSource; + UnitTestMockERC20 public mockERC20; + + event TransferToDestination( + address indexed sender, + address indexed recipient, + uint256 indexed teleporterMessageID, + uint256 amount + ); + event UnlockTokens(address recipient, uint256 amount); + event BurnTokens(uint256 amount); + + function setUp() public virtual { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector), + abi.encode(_MOCK_BLOCKCHAIN_ID) + ); + vm.mockCall( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + abi.encodeWithSelector( + ITeleporterMessenger.sendCrossChainMessage.selector + ), + abi.encode(1) + ); + + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector) + ); + + mockERC20 = new UnitTestMockERC20(); + erc20TokenSource = new ERC20TokenSource( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + address(mockERC20) + ); + + vm.mockCall( + address(mockERC20), + abi.encodeWithSelector(IERC20.allowance.selector), + abi.encode(1234) + ); + vm.mockCall( + address(mockERC20), + abi.encodeWithSelector(IERC20.approve.selector), + abi.encode(true) + ); + } + + function testTransferToDestination() public { + vm.expectEmit(true, true, true, true, address(erc20TokenSource)); + emit TransferToDestination({ + sender: address(this), + recipient: _DEFAULT_RECIPIENT, + amount: _DEFAULT_TRANSFER_AMOUNT, + teleporterMessageID: 1 + }); + + TeleporterMessageInput + memory expectedMessageInput = TeleporterMessageInput({ + destinationBlockchainID: _DEFAULT_OTHER_CHAIN_ID, + destinationAddress: _DEFAULT_OTHER_BRIDGE_ADDRESS, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: address(mockERC20), + amount: _DEFAULT_FEE_AMOUNT + }), + requiredGasLimit: erc20TokenSource + .MINT_NATIVE_TOKENS_REQUIRED_GAS(), + allowedRelayerAddresses: new address[](0), + message: abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + }); + + vm.expectCall( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + abi.encodeCall( + ITeleporterMessenger.sendCrossChainMessage, + (expectedMessageInput) + ) + ); + + erc20TokenSource.transferToDestination( + _DEFAULT_RECIPIENT, + _DEFAULT_TRANSFER_AMOUNT + _DEFAULT_FEE_AMOUNT, + _DEFAULT_FEE_AMOUNT, + new address[](0) + ); + } + + function testUnlock() public { + // Give the contract some tokens to burn. + erc20TokenSource.transferToDestination( + _DEFAULT_RECIPIENT, + _DEFAULT_TRANSFER_AMOUNT * 2 + _DEFAULT_FEE_AMOUNT , + _DEFAULT_FEE_AMOUNT, + new address[](0) + ); + + vm.expectEmit(true, true, true, true, address(erc20TokenSource)); + emit UnlockTokens(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + erc20TokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Unlock, + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + ) + ); + + assertEq(_DEFAULT_TRANSFER_AMOUNT, mockERC20.balanceOf(_DEFAULT_RECIPIENT)); + } + + function testBurnedTxFees() public { + // Give the contract some tokens to burn. + erc20TokenSource.transferToDestination( + _DEFAULT_RECIPIENT, + _DEFAULT_TRANSFER_AMOUNT + _DEFAULT_FEE_AMOUNT, + _DEFAULT_FEE_AMOUNT, + new address[](0) + ); + + uint256 burnedTxFees = 100; + uint256 additionalTxFees = 50; + assertEq(0, erc20TokenSource.destinationBurnedTotal()); + + vm.expectEmit(true, true, true, true, address(erc20TokenSource)); + emit BurnTokens(burnedTxFees); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + erc20TokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Burn, + abi.encode(burnedTxFees) + ) + ); + + assertEq(burnedTxFees, erc20TokenSource.destinationBurnedTotal()); + assertEq(burnedTxFees, mockERC20.balanceOf(erc20TokenSource.BURNED_TX_FEES_ADDRESS())); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + erc20TokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Burn, + abi.encode(burnedTxFees - 1) + ) + ); + + assertEq(burnedTxFees, erc20TokenSource.destinationBurnedTotal()); + assertEq(burnedTxFees, mockERC20.balanceOf(erc20TokenSource.BURNED_TX_FEES_ADDRESS())); + + emit BurnTokens(additionalTxFees); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + erc20TokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Burn, + abi.encode(burnedTxFees + additionalTxFees) + ) + ); + + assertEq(burnedTxFees + additionalTxFees, erc20TokenSource.destinationBurnedTotal()); + assertEq(burnedTxFees + additionalTxFees, mockERC20.balanceOf(erc20TokenSource.BURNED_TX_FEES_ADDRESS())); + } + + function testZeroTeleporterAddress() public { + vm.expectRevert( + _formatERC20TokenSourceErrorMessage( + "zero TeleporterMessenger address" + ) + ); + + new ERC20TokenSource( + address(0x0), + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + address(mockERC20) + ); + } + + function testZeroDestinationChainID() public { + vm.expectRevert( + _formatERC20TokenSourceErrorMessage( + "zero destination blockchain ID" + ) + ); + + new ERC20TokenSource( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + bytes32(0), + _DEFAULT_OTHER_BRIDGE_ADDRESS, + address(mockERC20) + ); + } + + function testSameBlockchainID() public { + vm.expectRevert( + _formatERC20TokenSourceErrorMessage( + "cannot bridge with same blockchain" + ) + ); + + new ERC20TokenSource( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + _MOCK_BLOCKCHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + address(mockERC20) + ); + } + + function testZeroDestinationContractAddress() public { + vm.expectRevert( + _formatERC20TokenSourceErrorMessage( + "zero destination contract address" + ) + ); + + new ERC20TokenSource( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + _DEFAULT_OTHER_CHAIN_ID, + address(0x0), + address(mockERC20) + ); + } + + function testZeroERC20ContractAddress() public { + vm.expectRevert( + _formatERC20TokenSourceErrorMessage( + "zero ERC20 contract address" + ) + ); + + new ERC20TokenSource( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + address(0x0) + ); + } + + function testInvalidTeleporterAddress() public { + vm.expectRevert( + _formatERC20TokenSourceErrorMessage( + "unauthorized TeleporterMessenger contract" + ) + ); + + vm.prank(address(0x123)); + erc20TokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Unlock, + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + ) + ); + } + + function testInvalidDestinationBlockchain() public { + vm.expectRevert( + _formatERC20TokenSourceErrorMessage("invalid destination chain") + ); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + erc20TokenSource.receiveTeleporterMessage( + _MOCK_BLOCKCHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Unlock, + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + ) + ); + } + + function testInvalidSenderContract() public { + vm.expectRevert( + _formatERC20TokenSourceErrorMessage("unauthorized sender") + ); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + erc20TokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + address(0x123), + abi.encode( + ITokenSource.SourceAction.Unlock, + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + ) + ); + } + + function testInvalidRecipientAddress() public { + vm.expectRevert( + _formatERC20TokenSourceErrorMessage("zero recipient address") + ); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + erc20TokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Unlock, + abi.encode(address(0x0), _DEFAULT_TRANSFER_AMOUNT) + ) + ); + } + + function testZeroRecipient() public { + vm.expectRevert( + _formatERC20TokenSourceErrorMessage("zero recipient address") + ); + + erc20TokenSource.transferToDestination( + address(0x0), + _DEFAULT_TRANSFER_AMOUNT + _DEFAULT_FEE_AMOUNT, + _DEFAULT_FEE_AMOUNT, + new address[](0) + ); + } + + function _formatERC20TokenSourceErrorMessage( + string memory errorMessage + ) private pure returns (bytes memory) { + return bytes(string.concat("ERC20TokenSource: ", errorMessage)); + } +} diff --git a/contracts/src/CrossChainApplications/NativeTokenBridge/tests/NativeTokenDestinationTests.t.sol b/contracts/src/CrossChainApplications/NativeTokenBridge/tests/NativeTokenDestinationTests.t.sol new file mode 100644 index 000000000..32e65b470 --- /dev/null +++ b/contracts/src/CrossChainApplications/NativeTokenBridge/tests/NativeTokenDestinationTests.t.sol @@ -0,0 +1,438 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.18; + +import {Test} from "forge-std/Test.sol"; +import {NativeTokenDestination, IERC20, ITokenSource, TeleporterMessageInput, TeleporterFeeInfo, IWarpMessenger, ITeleporterMessenger} from "../NativeTokenDestination.sol"; +import {UnitTestMockERC20} from "../../../Mocks/UnitTestMockERC20.sol"; +import {INativeMinter} from "@subnet-evm-contracts/interfaces/INativeMinter.sol"; + +contract NativeTokenDestinationTest is Test { + address public constant MOCK_TELEPORTER_MESSENGER_ADDRESS = + 0x644E5b7c5D4Bc8073732CEa72c66e0BB90dFC00f; + address public constant WARP_PRECOMPILE_ADDRESS = + address(0x0200000000000000000000000000000000000005); + address public constant NATIVE_MINTER_PRECOMPILE_ADDRESS = + address(0x0200000000000000000000000000000000000001); + bytes32 private constant _MOCK_BLOCKCHAIN_ID = bytes32(uint256(123456)); + bytes32 private constant _DEFAULT_OTHER_CHAIN_ID = + bytes32( + hex"abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd" + ); + address private constant _DEFAULT_OTHER_BRIDGE_ADDRESS = + 0xd54e3E251b9b0EEd3ed70A858e927bbC2659587d; + uint256 private constant _DEFAULT_INITIAL_RESERVE_IMBALANCE = 1000000000; + address private constant _DEFAULT_RECIPIENT = + 0xa4CEE7d1aF6aDdDD33E3b1cC680AB84fdf1b6d1d; + uint256 private constant _DEFAULT_TRANSFER_AMOUNT = 1e18; + uint256 private constant _DEFAULT_FEE_AMOUNT = 123456; + + NativeTokenDestination public nativeTokenDestination; + UnitTestMockERC20 public mockERC20; + + event TransferToSource( + address indexed sender, + address indexed recipient, + uint256 indexed teleporterMessageID, + uint256 amount + ); + event CollateralAdded(uint256 amount, uint256 remaining); + event NativeTokensMinted(address indexed recipient, uint256 amount); + event ReportTotalBurnedTxFees( + uint256 indexed teleporterMessageID, + uint256 burnAddressBalance + ); + + function setUp() public virtual { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector), + abi.encode(_MOCK_BLOCKCHAIN_ID) + ); + vm.mockCall( + NATIVE_MINTER_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(INativeMinter.mintNativeCoin.selector), + "" + ); + vm.mockCall( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + abi.encodeWithSelector( + ITeleporterMessenger.sendCrossChainMessage.selector + ), + abi.encode(1) + ); + + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector) + ); + + nativeTokenDestination = new NativeTokenDestination( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + _DEFAULT_INITIAL_RESERVE_IMBALANCE + ); + mockERC20 = new UnitTestMockERC20(); + + vm.mockCall( + address(mockERC20), + abi.encodeWithSelector(IERC20.allowance.selector), + abi.encode(1234) + ); + vm.mockCall( + address(mockERC20), + abi.encodeWithSelector(IERC20.approve.selector), + abi.encode(true) + ); + } + + function collateralizeBridge() public { + vm.expectEmit(true, true, true, true, address(nativeTokenDestination)); + emit CollateralAdded({ + amount: _DEFAULT_INITIAL_RESERVE_IMBALANCE, + remaining: 0 + }); + + // We shouldn't mint anything here. + vm.expectCall( + NATIVE_MINTER_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(INativeMinter.mintNativeCoin.selector), + 0 + ); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenDestination.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_INITIAL_RESERVE_IMBALANCE) + ); + vm.stopPrank(); + } + + function testTransferToSource() public { + collateralizeBridge(); + + vm.expectEmit(true, true, true, true, address(nativeTokenDestination)); + emit TransferToSource({ + sender: address(this), + recipient: _DEFAULT_RECIPIENT, + amount: _DEFAULT_TRANSFER_AMOUNT, + teleporterMessageID: 1 + }); + + TeleporterMessageInput + memory expectedMessageInput = TeleporterMessageInput({ + destinationBlockchainID: _DEFAULT_OTHER_CHAIN_ID, + destinationAddress: _DEFAULT_OTHER_BRIDGE_ADDRESS, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: address(mockERC20), + amount: _DEFAULT_FEE_AMOUNT + }), + requiredGasLimit: nativeTokenDestination + .TRANSFER_NATIVE_TOKENS_REQUIRED_GAS(), + allowedRelayerAddresses: new address[](0), + message: abi.encode( + ITokenSource.SourceAction.Unlock, + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + ) + }); + + vm.expectCall( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + abi.encodeCall( + ITeleporterMessenger.sendCrossChainMessage, + (expectedMessageInput) + ) + ); + + nativeTokenDestination.transferToSource{ + value: _DEFAULT_TRANSFER_AMOUNT + }( + _DEFAULT_RECIPIENT, + TeleporterFeeInfo({ + feeTokenAddress: address(mockERC20), + amount: _DEFAULT_FEE_AMOUNT + }), + new address[](0) + ); + } + + function testCollateralizeBridge() public { + uint256 firstTransfer = _DEFAULT_INITIAL_RESERVE_IMBALANCE / 4; + + assertEq(_DEFAULT_INITIAL_RESERVE_IMBALANCE, nativeTokenDestination.totalSupply()); + + vm.expectEmit(true, true, true, true, address(nativeTokenDestination)); + emit CollateralAdded({ + amount: firstTransfer, + remaining: _DEFAULT_INITIAL_RESERVE_IMBALANCE - firstTransfer + }); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenDestination.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode(_DEFAULT_RECIPIENT, firstTransfer) + ); + + assertEq(_DEFAULT_INITIAL_RESERVE_IMBALANCE - firstTransfer, nativeTokenDestination.currentReserveImbalance()); + assertEq(_DEFAULT_INITIAL_RESERVE_IMBALANCE, nativeTokenDestination.totalSupply()); + + vm.expectEmit(true, true, true, true, address(nativeTokenDestination)); + emit CollateralAdded({ + amount: _DEFAULT_INITIAL_RESERVE_IMBALANCE - firstTransfer, + remaining: 0 + }); + emit NativeTokensMinted(_DEFAULT_RECIPIENT, firstTransfer); + + vm.expectCall( + NATIVE_MINTER_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(INativeMinter.mintNativeCoin.selector), + 1 + ); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenDestination.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_INITIAL_RESERVE_IMBALANCE) + ); + + assertEq(0, nativeTokenDestination.currentReserveImbalance()); + assertEq(_DEFAULT_INITIAL_RESERVE_IMBALANCE + firstTransfer, nativeTokenDestination.totalSupply()); + } + + function testReportBurnedTxFees() public { + uint256 burnedFees = nativeTokenDestination + .BURNED_TX_FEES_ADDRESS() + .balance; + + vm.expectEmit(true, true, true, true, address(nativeTokenDestination)); + emit ReportTotalBurnedTxFees({ + burnAddressBalance: burnedFees, + teleporterMessageID: 1 + }); + + TeleporterMessageInput + memory expectedMessageInput = TeleporterMessageInput({ + destinationBlockchainID: _DEFAULT_OTHER_CHAIN_ID, + destinationAddress: _DEFAULT_OTHER_BRIDGE_ADDRESS, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: address(mockERC20), + amount: _DEFAULT_FEE_AMOUNT + }), + requiredGasLimit: nativeTokenDestination + .REPORT_BURNED_TOKENS_REQUIRED_GAS(), + allowedRelayerAddresses: new address[](0), + message: abi.encode( + ITokenSource.SourceAction.Burn, + abi.encode(burnedFees) + ) + }); + + vm.expectCall( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + abi.encodeCall( + ITeleporterMessenger.sendCrossChainMessage, + (expectedMessageInput) + ) + ); + + nativeTokenDestination.reportTotalBurnedTxFees( + TeleporterFeeInfo({ + feeTokenAddress: address(mockERC20), + amount: _DEFAULT_FEE_AMOUNT + }), + new address[](0) + ); + } + + function testZeroTeleporterAddress() public { + vm.expectRevert( + _formatNativeTokenDestinationErrorMessage( + "zero TeleporterMessenger address" + ) + ); + + new NativeTokenDestination( + address(0x0), + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + _DEFAULT_INITIAL_RESERVE_IMBALANCE + ); + } + + function testZeroSourceChainID() public { + vm.expectRevert( + _formatNativeTokenDestinationErrorMessage( + "zero source blockchain ID" + ) + ); + + new NativeTokenDestination( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + bytes32(0), + _DEFAULT_OTHER_BRIDGE_ADDRESS, + _DEFAULT_INITIAL_RESERVE_IMBALANCE + ); + } + + function testSameBlockchainID() public { + vm.expectRevert( + _formatNativeTokenDestinationErrorMessage( + "cannot bridge with same blockchain" + ) + ); + + new NativeTokenDestination( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + _MOCK_BLOCKCHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + _DEFAULT_INITIAL_RESERVE_IMBALANCE + ); + } + + function testZeroSourceContractAddress() public { + vm.expectRevert( + _formatNativeTokenDestinationErrorMessage( + "zero source contract address" + ) + ); + + new NativeTokenDestination( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + _DEFAULT_OTHER_CHAIN_ID, + address(0x0), + _DEFAULT_INITIAL_RESERVE_IMBALANCE + ); + } + + function testZeroInitialReserveImbalance() public { + vm.expectRevert( + _formatNativeTokenDestinationErrorMessage( + "zero initial reserve imbalance" + ) + ); + + new NativeTokenDestination( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + 0 + ); + } + + function testInvalidTeleporterAddress() public { + vm.expectRevert( + _formatNativeTokenDestinationErrorMessage( + "unauthorized TeleporterMessenger contract" + ) + ); + + vm.prank(address(0x123)); + nativeTokenDestination.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + ); + } + + function testInvalidSourceBlockchain() public { + vm.expectRevert( + _formatNativeTokenDestinationErrorMessage("invalid source chain") + ); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenDestination.receiveTeleporterMessage( + _MOCK_BLOCKCHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + ); + } + + function testInvalidSenderContract() public { + vm.expectRevert( + _formatNativeTokenDestinationErrorMessage("unauthorized sender") + ); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenDestination.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + address(0x123), + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + ); + } + + function testInvalidRecipientAddress() public { + vm.expectRevert( + _formatNativeTokenDestinationErrorMessage("zero recipient address") + ); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenDestination.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode(address(0x0), _DEFAULT_TRANSFER_AMOUNT) + ); + } + + function testInvalidTransferAmount() public { + vm.expectRevert( + _formatNativeTokenDestinationErrorMessage("zero transfer value") + ); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenDestination.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode(_DEFAULT_RECIPIENT, 0) + ); + } + + function testZeroRecipient() public { + collateralizeBridge(); + vm.expectRevert( + _formatNativeTokenDestinationErrorMessage("zero recipient address") + ); + + nativeTokenDestination.transferToSource{ + value: _DEFAULT_TRANSFER_AMOUNT + }( + address(0x0), + TeleporterFeeInfo({ + feeTokenAddress: address(mockERC20), + amount: _DEFAULT_FEE_AMOUNT + }), + new address[](0) + ); + } + + function testUncollateralizedBridge() public { + vm.expectRevert( + _formatNativeTokenDestinationErrorMessage( + "contract undercollateralized" + ) + ); + + nativeTokenDestination.transferToSource{ + value: _DEFAULT_TRANSFER_AMOUNT + }( + _DEFAULT_RECIPIENT, + TeleporterFeeInfo({ + feeTokenAddress: address(mockERC20), + amount: _DEFAULT_FEE_AMOUNT + }), + new address[](0) + ); + } + + function _formatNativeTokenDestinationErrorMessage( + string memory errorMessage + ) private pure returns (bytes memory) { + return bytes(string.concat("NativeTokenDestination: ", errorMessage)); + } +} diff --git a/contracts/src/CrossChainApplications/NativeTokenBridge/tests/NativeTokenSourceTests.t.sol b/contracts/src/CrossChainApplications/NativeTokenBridge/tests/NativeTokenSourceTests.t.sol new file mode 100644 index 000000000..0091ca6f0 --- /dev/null +++ b/contracts/src/CrossChainApplications/NativeTokenBridge/tests/NativeTokenSourceTests.t.sol @@ -0,0 +1,374 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.18; + +import {Test} from "forge-std/Test.sol"; +import {NativeTokenSource, IERC20, ITokenSource, TeleporterMessageInput, TeleporterFeeInfo, IWarpMessenger, ITeleporterMessenger} from "../NativeTokenSource.sol"; +import {UnitTestMockERC20} from "../../../Mocks/UnitTestMockERC20.sol"; + +contract NativeTokenSourceTest is Test { + address public constant MOCK_TELEPORTER_MESSENGER_ADDRESS = + 0x644E5b7c5D4Bc8073732CEa72c66e0BB90dFC00f; + address public constant WARP_PRECOMPILE_ADDRESS = + address(0x0200000000000000000000000000000000000005); + bytes32 private constant _MOCK_BLOCKCHAIN_ID = bytes32(uint256(123456)); + bytes32 private constant _DEFAULT_OTHER_CHAIN_ID = + bytes32( + hex"abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd" + ); + address private constant _DEFAULT_OTHER_BRIDGE_ADDRESS = + 0xd54e3E251b9b0EEd3ed70A858e927bbC2659587d; + uint256 private constant _DEFAULT_INITIAL_RESERVE_IMBALANCE = 1000000000; + address private constant _DEFAULT_RECIPIENT = + 0xa4CEE7d1aF6aDdDD33E3b1cC680AB84fdf1b6d1d; + uint256 private constant _DEFAULT_TRANSFER_AMOUNT = 1e18; + uint256 private constant _DEFAULT_FEE_AMOUNT = 123456; + + NativeTokenSource public nativeTokenSource; + UnitTestMockERC20 public mockERC20; + + event TransferToDestination( + address indexed sender, + address indexed recipient, + uint256 indexed teleporterMessageID, + uint256 amount + ); + event UnlockTokens(address recipient, uint256 amount); + event BurnTokens(uint256 amount); + + function setUp() public virtual { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector), + abi.encode(_MOCK_BLOCKCHAIN_ID) + ); + vm.mockCall( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + abi.encodeWithSelector( + ITeleporterMessenger.sendCrossChainMessage.selector + ), + abi.encode(1) + ); + + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector) + ); + + nativeTokenSource = new NativeTokenSource( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS + ); + mockERC20 = new UnitTestMockERC20(); + + vm.mockCall( + address(mockERC20), + abi.encodeWithSelector(IERC20.allowance.selector), + abi.encode(1234) + ); + vm.mockCall( + address(mockERC20), + abi.encodeWithSelector(IERC20.approve.selector), + abi.encode(true) + ); + } + + function testTransferToDestination() public { + vm.expectEmit(true, true, true, true, address(nativeTokenSource)); + emit TransferToDestination({ + sender: address(this), + recipient: _DEFAULT_RECIPIENT, + amount: _DEFAULT_TRANSFER_AMOUNT, + teleporterMessageID: 1 + }); + + TeleporterMessageInput + memory expectedMessageInput = TeleporterMessageInput({ + destinationBlockchainID: _DEFAULT_OTHER_CHAIN_ID, + destinationAddress: _DEFAULT_OTHER_BRIDGE_ADDRESS, + feeInfo: TeleporterFeeInfo({ + feeTokenAddress: address(mockERC20), + amount: _DEFAULT_FEE_AMOUNT + }), + requiredGasLimit: nativeTokenSource + .MINT_NATIVE_TOKENS_REQUIRED_GAS(), + allowedRelayerAddresses: new address[](0), + message: abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + }); + + vm.expectCall( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + abi.encodeCall( + ITeleporterMessenger.sendCrossChainMessage, + (expectedMessageInput) + ) + ); + + nativeTokenSource.transferToDestination{ + value: _DEFAULT_TRANSFER_AMOUNT + }( + _DEFAULT_RECIPIENT, + TeleporterFeeInfo({ + feeTokenAddress: address(mockERC20), + amount: _DEFAULT_FEE_AMOUNT + }), + new address[](0) + ); + } + + function testUnlock() public { + // Give the contract some tokens to burn. + nativeTokenSource.transferToDestination{ + value: _DEFAULT_TRANSFER_AMOUNT * 2 + }( + _DEFAULT_RECIPIENT, + TeleporterFeeInfo({ + feeTokenAddress: address(mockERC20), + amount: _DEFAULT_FEE_AMOUNT + }), + new address[](0) + ); + + vm.expectEmit(true, true, true, true, address(nativeTokenSource)); + emit UnlockTokens(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Unlock, + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + ) + ); + + assertEq(_DEFAULT_TRANSFER_AMOUNT, _DEFAULT_RECIPIENT.balance); + } + + function testBurnedTxFees() public { + // Give the contract some tokens to burn. + nativeTokenSource.transferToDestination{ + value: _DEFAULT_TRANSFER_AMOUNT + }( + _DEFAULT_RECIPIENT, + TeleporterFeeInfo({ + feeTokenAddress: address(mockERC20), + amount: _DEFAULT_FEE_AMOUNT + }), + new address[](0) + ); + + uint256 burnedTxFees = 100; + uint256 additionalTxFees = 50; + assertEq(0, nativeTokenSource.destinationBurnedTotal()); + + vm.expectEmit(true, true, true, true, address(nativeTokenSource)); + emit BurnTokens(burnedTxFees); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Burn, + abi.encode(burnedTxFees) + ) + ); + + assertEq(burnedTxFees, nativeTokenSource.destinationBurnedTotal()); + assertEq(burnedTxFees, nativeTokenSource.BURNED_TX_FEES_ADDRESS().balance); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Burn, + abi.encode(burnedTxFees - 1) + ) + ); + + assertEq(burnedTxFees, nativeTokenSource.destinationBurnedTotal()); + assertEq(burnedTxFees, nativeTokenSource.BURNED_TX_FEES_ADDRESS().balance); + + emit BurnTokens(additionalTxFees); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Burn, + abi.encode(burnedTxFees + additionalTxFees) + ) + ); + + assertEq(burnedTxFees + additionalTxFees, nativeTokenSource.destinationBurnedTotal()); + assertEq(burnedTxFees + additionalTxFees, nativeTokenSource.BURNED_TX_FEES_ADDRESS().balance); + } + + function testZeroTeleporterAddress() public { + vm.expectRevert( + _formatNativeTokenSourceErrorMessage( + "zero TeleporterMessenger address" + ) + ); + + new NativeTokenSource( + address(0x0), + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS + ); + } + + function testZeroDestinationChainID() public { + vm.expectRevert( + _formatNativeTokenSourceErrorMessage( + "zero destination blockchain ID" + ) + ); + + new NativeTokenSource( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + bytes32(0), + _DEFAULT_OTHER_BRIDGE_ADDRESS + ); + } + + function testSameBlockchainID() public { + vm.expectRevert( + _formatNativeTokenSourceErrorMessage( + "cannot bridge with same blockchain" + ) + ); + + new NativeTokenSource( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + _MOCK_BLOCKCHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS + ); + } + + function testZeroDestinationContractAddress() public { + vm.expectRevert( + _formatNativeTokenSourceErrorMessage( + "zero destination contract address" + ) + ); + + new NativeTokenSource( + MOCK_TELEPORTER_MESSENGER_ADDRESS, + _DEFAULT_OTHER_CHAIN_ID, + address(0x0) + ); + } + + function testInvalidTeleporterAddress() public { + vm.expectRevert( + _formatNativeTokenSourceErrorMessage( + "unauthorized TeleporterMessenger contract" + ) + ); + + vm.prank(address(0x123)); + nativeTokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Unlock, + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + ) + ); + } + + function testInvalidDestinationBlockchain() public { + vm.expectRevert( + _formatNativeTokenSourceErrorMessage("invalid destination chain") + ); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenSource.receiveTeleporterMessage( + _MOCK_BLOCKCHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Unlock, + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + ) + ); + } + + function testInvalidSenderContract() public { + vm.expectRevert( + _formatNativeTokenSourceErrorMessage("unauthorized sender") + ); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + address(0x123), + abi.encode( + ITokenSource.SourceAction.Unlock, + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + ) + ); + } + + function testInvalidRecipientAddress() public { + vm.expectRevert( + _formatNativeTokenSourceErrorMessage("zero recipient address") + ); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Unlock, + abi.encode(address(0x0), _DEFAULT_TRANSFER_AMOUNT) + ) + ); + } + + function testZeroRecipient() public { + vm.expectRevert( + _formatNativeTokenSourceErrorMessage("zero recipient address") + ); + + nativeTokenSource.transferToDestination{ + value: _DEFAULT_TRANSFER_AMOUNT + }( + address(0x0), + TeleporterFeeInfo({ + feeTokenAddress: address(mockERC20), + amount: _DEFAULT_FEE_AMOUNT + }), + new address[](0) + ); + } + + function testInsufficientCollateral() public { + vm.expectRevert( + _formatNativeTokenSourceErrorMessage("insufficient collateral") + ); + + vm.prank(MOCK_TELEPORTER_MESSENGER_ADDRESS); + nativeTokenSource.receiveTeleporterMessage( + _DEFAULT_OTHER_CHAIN_ID, + _DEFAULT_OTHER_BRIDGE_ADDRESS, + abi.encode( + ITokenSource.SourceAction.Unlock, + abi.encode(_DEFAULT_RECIPIENT, _DEFAULT_TRANSFER_AMOUNT) + ) + ); + } + + function _formatNativeTokenSourceErrorMessage( + string memory errorMessage + ) private pure returns (bytes memory) { + return bytes(string.concat("NativeTokenSource: ", errorMessage)); + } +} diff --git a/contracts/src/Mocks/UnitTestMockERC20.sol b/contracts/src/Mocks/UnitTestMockERC20.sol index e01ae4277..9217604a6 100644 --- a/contracts/src/Mocks/UnitTestMockERC20.sol +++ b/contracts/src/Mocks/UnitTestMockERC20.sol @@ -30,6 +30,18 @@ contract UnitTestMockERC20 { return true; } + // The mock allows anyone to call transferFrom to increment the balance of the + // receipt address. Neither the caller or sender need to have sufficient balances to send, + // we just increment the balance the of the recipient. + function transfer( + address to, + uint256 amount + ) public returns (bool) { + uint256 feeAmount = feeOnTransferSenders[msg.sender]; + mockBalances[to] += (amount - feeAmount); + return true; + } + function balanceOf(address account) public view returns (uint256) { return mockBalances[account]; } diff --git a/docker/Dockerfile b/docker/Dockerfile index 418ff7ab0..cc96f6398 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -3,6 +3,8 @@ FROM ubuntu:20.04 +RUN set -e + ARG DEBIAN_FRONTEND=noninteractive # defaults to amd64. needs to be arm64 for Macos M1 diff --git a/scripts/abi_bindings.sh b/scripts/abi_bindings.sh index 0220cd370..aa5faed3d 100755 --- a/scripts/abi_bindings.sh +++ b/scripts/abi_bindings.sh @@ -15,7 +15,7 @@ source $TELEPORTER_PATH/scripts/versions.sh setARCH -DEFAULT_CONTRACT_LIST="TeleporterMessenger ERC20Bridge ExampleCrossChainMessenger BlockHashPublisher BlockHashReceiver BridgeToken TeleporterRegistry ExampleERC20" +DEFAULT_CONTRACT_LIST="TeleporterMessenger ERC20Bridge ExampleCrossChainMessenger BlockHashPublisher BlockHashReceiver BridgeToken TeleporterRegistry NativeTokenSource NativeTokenDestination ERC20TokenSource ExampleERC20" CONTRACT_LIST= HELP= diff --git a/scripts/local/run_stop.sh b/scripts/local/run_stop.sh index b9b7f2c4b..4c01f86d9 100755 --- a/scripts/local/run_stop.sh +++ b/scripts/local/run_stop.sh @@ -5,11 +5,6 @@ set -e # Stop on first error source ./scripts/utils.sh -# Set ARCH env so as a container executes without issues in a portable way -# Should be amd64 for linux/macos x86 hosts, and arm64 for macos M1 -# It is referenced in the docker composer yaml, and then passed as a Dockerfile ARG -setARCH - if [[ $# -gt 1 ]]; then echo "Invalid number of arguments. Usage:" echo " ./scripts/local/run_stop.sh # stop the running containers and preserve the network for subsequent runs" diff --git a/tests/flows/erc20_to_native_token_bridge.go b/tests/flows/erc20_to_native_token_bridge.go new file mode 100644 index 000000000..61ec05dd5 --- /dev/null +++ b/tests/flows/erc20_to_native_token_bridge.go @@ -0,0 +1,354 @@ +package flows + +import ( + "context" + "crypto/ecdsa" + "math/big" + + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + erc20tokensource "github.com/ava-labs/teleporter/abi-bindings/go/CrossChainApplications/NativeTokenBridge/ERC20TokenSource" + nativetokendestination "github.com/ava-labs/teleporter/abi-bindings/go/CrossChainApplications/NativeTokenBridge/NativeTokenDestination" + exampleerc20 "github.com/ava-labs/teleporter/abi-bindings/go/Mocks/ExampleERC20" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ava-labs/teleporter/tests/utils" + deploymentUtils "github.com/ava-labs/teleporter/utils/deployment-utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + . "github.com/onsi/gomega" +) + +func ERC20ToNativeTokenBridge(network interfaces.LocalNetwork) { + const ( + // This test needs a unique deployer key, whose nonce 0 is used to deploy the bridge contract + // on each chain. The address of the resulting contract has been added to the genesis file as + // an admin for the Native Minter precompile. + deployerKeyStr = "ca7269c1fe2a5b86884a119aa516b8d5b641670b83aac0ebf9f2d71affcc12e4" + ExampleERC20ByteCodeFile = "./contracts/out/ExampleERC20.sol/ExampleERC20.json" + ERC20TokenSourceByteCodeFile = "./contracts/out/ERC20TokenSource.sol/ERC20TokenSource.json" + NativeTokenDestinationByteCodeFile = "./contracts/out/NativeTokenDestination.sol/NativeTokenDestination.json" + ) + var ( + initialReserveImbalance = big.NewInt(0).Mul(big.NewInt(1e15), big.NewInt(1e9)) + valueToSend = big.NewInt(0).Div(initialReserveImbalance, big.NewInt(4)) + intermediateReserveImbalance = utils.BigIntSub(initialReserveImbalance, valueToSend) + valueToReturn = big.NewInt(0).Div(valueToSend, big.NewInt(4)) + + ctx = context.Background() + deployerAddress = common.HexToAddress("0x539447ab8Be7e927bE8E005663C81ff2AE951337") + tokenReceiverAddress = common.HexToAddress("0x4444444444444444444444444444444444444444") + burnedTxFeeAddress = common.HexToAddress("0x0100000000000000000000000000000000000000") + + emptyDestFeeInfo = nativetokendestination.TeleporterFeeInfo{ + FeeTokenAddress: common.Address{}, + Amount: common.Big0, + } + ) + + sourceSubnet, destSubnet, _ := utils.GetThreeSubnets(network) + teleporterContractAddress := network.GetTeleporterContractAddress() + + // Info we need to calculate for the test + deployerPK, err := crypto.HexToECDSA(deployerKeyStr) + Expect(err).Should(BeNil()) + bridgeContractAddress, err := deploymentUtils.DeriveEVMContractAddress(deployerAddress, 0) + Expect(err).Should(BeNil()) + log.Info("Native Token Bridge Contract Address: " + bridgeContractAddress.Hex()) + exampleERC20ContractAddress, err := deploymentUtils.DeriveEVMContractAddress(deployerAddress, 1) + Expect(err).Should(BeNil()) + log.Info("Example ERC20 Contract Address: " + exampleERC20ContractAddress.Hex()) + + // Deploy the contracts + // Both contracts in this test will be deployed to 0x3405506b3711859c5070949ed9b700c7ba7bf750, + // though they do not necessarily have to be deployed at the same address, each contract needs + // to know the address of the other. + // The nativeTokenDestination contract must be added to "adminAddresses" of "contractNativeMinterConfig" + // in the genesis file for the subnet. This will allow it to call the native minter precompile. + erc20TokenSourceAbi, err := erc20tokensource.ERC20TokenSourceMetaData.GetAbi() + Expect(err).Should(BeNil()) + utils.DeployContract( + ctx, + ERC20TokenSourceByteCodeFile, + deployerPK, + sourceSubnet, + erc20TokenSourceAbi, + teleporterContractAddress, + destSubnet.BlockchainID, + bridgeContractAddress, + exampleERC20ContractAddress, + ) + + nativeTokenDestinationAbi, err := nativetokendestination.NativeTokenDestinationMetaData.GetAbi() + Expect(err).Should(BeNil()) + utils.DeployContract( + ctx, + NativeTokenDestinationByteCodeFile, + deployerPK, + destSubnet, + nativeTokenDestinationAbi, + teleporterContractAddress, + sourceSubnet.BlockchainID, + bridgeContractAddress, + initialReserveImbalance, + ) + + exampleERC20Abi, err := exampleerc20.ExampleERC20MetaData.GetAbi() + Expect(err).Should(BeNil()) + utils.DeployContract(ctx, ExampleERC20ByteCodeFile, deployerPK, sourceSubnet, exampleERC20Abi) + + log.Info("Finished deploying contracts") + + // Create abi objects to call the contract with + nativeTokenDestination, err := nativetokendestination.NewNativeTokenDestination( + bridgeContractAddress, + destSubnet.WSClient, + ) + Expect(err).Should(BeNil()) + erc20TokenSource, err := erc20tokensource.NewERC20TokenSource( + bridgeContractAddress, + sourceSubnet.WSClient, + ) + Expect(err).Should(BeNil()) + exampleERC20, err := exampleerc20.NewExampleERC20( + exampleERC20ContractAddress, + sourceSubnet.WSClient, + ) + Expect(err).Should(BeNil()) + + { + // Give erc20TokenSource allowance to spend all of the deployer's ERC20 Tokens + bal, err := exampleERC20.BalanceOf(nil, deployerAddress) + Expect(err).Should(BeNil()) + + transactor, err := bind.NewKeyedTransactorWithChainID(deployerPK, sourceSubnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := exampleERC20.Approve(transactor, bridgeContractAddress, bal) + Expect(err).Should(BeNil()) + + utils.WaitForTransactionSuccess(ctx, tx.Hash(), sourceSubnet) + } + + { + // Transfer some tokens A -> B + // Check starting balance is 0 + utils.CheckBalance(ctx, tokenReceiverAddress, common.Big0, destSubnet.WSClient) + + checkReserveImbalance(initialReserveImbalance, nativeTokenDestination) + + destChainReceipt := + sendERC20TokensToDestination( + ctx, + network, + valueToSend, + deployerPK, + tokenReceiverAddress, + sourceSubnet, + destSubnet, + erc20TokenSource, + common.Big0, + ) + + collateralEvent, err := utils.GetEventFromLogs( + destChainReceipt.Logs, + nativeTokenDestination.ParseCollateralAdded, + ) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(collateralEvent.Amount, valueToSend) + + _, err = utils.GetEventFromLogs( + destChainReceipt.Logs, + nativeTokenDestination.ParseNativeTokensMinted, + ) + Expect(err).ShouldNot(BeNil()) + + checkReserveImbalance(intermediateReserveImbalance, nativeTokenDestination) + + // Check intermediate balance, no tokens should be minted because we haven't collateralized + utils.CheckBalance(ctx, tokenReceiverAddress, common.Big0, destSubnet.WSClient) + } + + { + // Fail to Transfer tokens B -> A because bridge is not collateralized + // Check starting balance is 0 + utils.CheckBalance(ctx, tokenReceiverAddress, common.Big0, destSubnet.WSClient) + + transactor, err := bind.NewKeyedTransactorWithChainID(deployerPK, destSubnet.EVMChainID) + Expect(err).Should(BeNil()) + transactor.Value = valueToSend + + _, err = nativeTokenDestination.TransferToSource( + transactor, + tokenReceiverAddress, + emptyDestFeeInfo, + []common.Address{}, + ) + Expect(err).ShouldNot(BeNil()) + + checkReserveImbalance(intermediateReserveImbalance, nativeTokenDestination) + + // Check we failed to send because we're not collateralized + utils.CheckBalance(ctx, tokenReceiverAddress, common.Big0, destSubnet.WSClient) + } + + { + // Transfer more tokens A -> B to collateralize the bridge + // Check starting balance is 0 + utils.CheckBalance(ctx, tokenReceiverAddress, common.Big0, destSubnet.WSClient) + + checkReserveImbalance(intermediateReserveImbalance, nativeTokenDestination) + + destChainReceipt := sendERC20TokensToDestination( + ctx, + network, + initialReserveImbalance, + deployerPK, + tokenReceiverAddress, + sourceSubnet, + destSubnet, + erc20TokenSource, + common.Big0, + ) + + collateralEvent, err := utils.GetEventFromLogs( + destChainReceipt.Logs, + nativeTokenDestination.ParseCollateralAdded, + ) + Expect(err).Should(BeNil()) + Expect(collateralEvent.Amount).Should(Equal(intermediateReserveImbalance)) + + mintEvent, err := utils.GetEventFromLogs( + destChainReceipt.Logs, + nativeTokenDestination.ParseNativeTokensMinted, + ) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(mintEvent.Amount, valueToSend) + + checkReserveImbalance(common.Big0, nativeTokenDestination) + + // We should have minted the excess coins after checking the collateral + utils.CheckBalance(ctx, tokenReceiverAddress, valueToSend, destSubnet.WSClient) + } + + { + // Transfer tokens B -> A + sourceChainReceipt := + sendTokensToSource( + ctx, + network, + valueToReturn, + deployerPK, + tokenReceiverAddress, + sourceSubnet, + destSubnet, + nativeTokenDestination, + emptyDestFeeInfo, + ) + + checkUnlockERC20Event( + sourceChainReceipt.Logs, + erc20TokenSource, + tokenReceiverAddress, + valueToReturn, + ) + + bal, err := exampleERC20.BalanceOf(nil, tokenReceiverAddress) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(bal, valueToReturn) + } + + { + // Check reporting of burned tx fees to Source Chain + burnedTxFeesBalanceDest, err := destSubnet.WSClient.BalanceAt( + ctx, + burnedTxFeeAddress, + nil, + ) + Expect(err).Should(BeNil()) + Expect(burnedTxFeesBalanceDest.Cmp(common.Big0) > 0).Should(BeTrue()) + + transactor, err := bind.NewKeyedTransactorWithChainID(deployerPK, destSubnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := nativeTokenDestination.ReportTotalBurnedTxFees( + transactor, + emptyDestFeeInfo, + []common.Address{}, + ) + Expect(err).Should(BeNil()) + + destChainReceipt := utils.WaitForTransactionSuccess(ctx, tx.Hash(), destSubnet) + + reportEvent, err := utils.GetEventFromLogs( + destChainReceipt.Logs, + nativeTokenDestination.ParseReportTotalBurnedTxFees, + ) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(reportEvent.BurnAddressBalance, burnedTxFeesBalanceDest) + + burnedTxFeesBalanceSource, err := exampleERC20.BalanceOf(nil, burnedTxFeeAddress) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(burnedTxFeesBalanceSource, common.Big0) + + sourceChainReceipt := network.RelayMessage(ctx, destChainReceipt, destSubnet, sourceSubnet, true) + + burnEvent, err := utils.GetEventFromLogs( + sourceChainReceipt.Logs, + erc20TokenSource.ParseBurnTokens, + ) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(burnedTxFeesBalanceDest, burnEvent.Amount) + + burnedTxFeesBalanceSource2, err := exampleERC20.BalanceOf(nil, burnedTxFeeAddress) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(burnedTxFeesBalanceSource2, burnEvent.Amount) + } +} + +func checkUnlockERC20Event( + logs []*types.Log, + erc20TokenSource *erc20tokensource.ERC20TokenSource, + recipient common.Address, + value *big.Int, +) { + unlockEvent, err := utils.GetEventFromLogs(logs, erc20TokenSource.ParseUnlockTokens) + Expect(err).Should(BeNil()) + Expect(unlockEvent.Recipient).Should(Equal(recipient)) + utils.ExpectBigEqual(unlockEvent.Amount, value) +} + +func sendERC20TokensToDestination( + ctx context.Context, + network interfaces.LocalNetwork, + valueToSend *big.Int, + fromKey *ecdsa.PrivateKey, + toAddress common.Address, + sourceSubnet interfaces.SubnetTestInfo, + destinationSubnet interfaces.SubnetTestInfo, + erc20TokenSource *erc20tokensource.ERC20TokenSource, + feeAmount *big.Int, +) *types.Receipt { + transactor, err := bind.NewKeyedTransactorWithChainID(fromKey, sourceSubnet.EVMChainID) + Expect(err).Should(BeNil()) + + tx, err := erc20TokenSource.TransferToDestination( + transactor, + toAddress, + valueToSend, + feeAmount, + []common.Address{}, + ) + Expect(err).Should(BeNil()) + + sourceChainReceipt := utils.WaitForTransactionSuccess(ctx, tx.Hash(), sourceSubnet) + + transferEvent, err := utils.GetEventFromLogs( + sourceChainReceipt.Logs, + erc20TokenSource.ParseTransferToDestination, + ) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(transferEvent.Amount, valueToSend) + + receipt := network.RelayMessage(ctx, sourceChainReceipt, sourceSubnet, destinationSubnet, true) + + return receipt +} diff --git a/tests/flows/native_token_bridge.go b/tests/flows/native_token_bridge.go new file mode 100644 index 000000000..4ab292e6d --- /dev/null +++ b/tests/flows/native_token_bridge.go @@ -0,0 +1,415 @@ +package flows + +import ( + "context" + "crypto/ecdsa" + "math/big" + + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + nativetokendestination "github.com/ava-labs/teleporter/abi-bindings/go/CrossChainApplications/NativeTokenBridge/NativeTokenDestination" + nativetokensource "github.com/ava-labs/teleporter/abi-bindings/go/CrossChainApplications/NativeTokenBridge/NativeTokenSource" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ava-labs/teleporter/tests/utils" + deploymentUtils "github.com/ava-labs/teleporter/utils/deployment-utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + . "github.com/onsi/gomega" +) + +func NativeTokenBridge(network interfaces.LocalNetwork) { + const ( + // This test needs a unique deployer key, whose nonce 0 is used to deploy the bridge contract + // on each chain. The address of the resulting contract has been added to the genesis file as + // an admin for the Native Minter precompile. + deployerKeyStr = "aad7440febfc8f9d73a58c3cb1f1754779a566978f9ebffcd4f4698e9b043985" + NativeTokenSourceByteCodeFile = "./contracts/out/NativeTokenSource.sol/NativeTokenSource.json" + NativeTokenDestinationByteCodeFile = "./contracts/out/NativeTokenDestination.sol/NativeTokenDestination.json" + ) + var ( + initialReserveImbalance = big.NewInt(0).Mul(big.NewInt(1e15), big.NewInt(1e9)) + valueToSend = big.NewInt(0).Div(initialReserveImbalance, big.NewInt(4)) + valueToReturn = big.NewInt(0).Div(valueToSend, big.NewInt(4)) + ctx = context.Background() + deployerAddress = common.HexToAddress("0x1337cfd2dCff6270615B90938aCB1efE79801704") + tokenReceiverAddress = common.HexToAddress("0x0123456789012345678901234567890123456789") + burnedTxFeeAddress = common.HexToAddress("0x0100000000000000000000000000000000000000") + + emptyDestFeeInfo = nativetokendestination.TeleporterFeeInfo{ + FeeTokenAddress: common.Address{}, + Amount: common.Big0, + } + emptySourceFeeInfo = nativetokensource.TeleporterFeeInfo{ + FeeTokenAddress: common.Address{}, + Amount: common.Big0, + } + ) + + sourceSubnet, destSubnet, _ := utils.GetThreeSubnets(network) + teleporterContractAddress := network.GetTeleporterContractAddress() + + // Info we need to calculate for the test + deployerPK, err := crypto.HexToECDSA(deployerKeyStr) + Expect(err).Should(BeNil()) + bridgeContractAddress, err := deploymentUtils.DeriveEVMContractAddress(deployerAddress, 0) + Expect(err).Should(BeNil()) + log.Info("Native Token Bridge Contract Address: " + bridgeContractAddress.Hex()) + + { + // Deploy the contracts + // Both contracts in this test will be deployed to 0xAcB633F5B00099c7ec187eB00156c5cd9D854b5B, + // though they do not necessarily have to be deployed at the same address, each contract needs + // to know the address of the other. + // The nativeTokenDestination contract must be added to "adminAddresses" of "contractNativeMinterConfig" + // in the genesis file for the subnet. This will allow it to call the native minter precompile. + erc20TokenSourceAbi, err := nativetokensource.NativeTokenSourceMetaData.GetAbi() + Expect(err).Should(BeNil()) + utils.DeployContract( + ctx, + NativeTokenSourceByteCodeFile, + deployerPK, + sourceSubnet, + erc20TokenSourceAbi, + teleporterContractAddress, + destSubnet.BlockchainID, + bridgeContractAddress, + ) + Expect(err).Should(BeNil()) + + nativeTokenDestinationAbi, err := nativetokendestination.NativeTokenDestinationMetaData.GetAbi() + Expect(err).Should(BeNil()) + utils.DeployContract( + ctx, + NativeTokenDestinationByteCodeFile, + deployerPK, + destSubnet, + nativeTokenDestinationAbi, + teleporterContractAddress, + sourceSubnet.BlockchainID, + bridgeContractAddress, + initialReserveImbalance, + ) + + log.Info("Finished deploying Bridge contracts") + } + + // Create abi objects to call the contract with + nativeTokenDestination, err := nativetokendestination.NewNativeTokenDestination( + bridgeContractAddress, + destSubnet.WSClient, + ) + Expect(err).Should(BeNil()) + nativeTokenSource, err := nativetokensource.NewNativeTokenSource( + bridgeContractAddress, + sourceSubnet.WSClient, + ) + Expect(err).Should(BeNil()) + + { + // Transfer some tokens A -> B + // Check starting balance is 0 + utils.CheckBalance(ctx, tokenReceiverAddress, common.Big0, destSubnet.WSClient) + + checkReserveImbalance(initialReserveImbalance, nativeTokenDestination) + + destChainReceipt := + sendNativeTokensToDestination( + ctx, + network, + valueToSend, + deployerPK, + tokenReceiverAddress, + sourceSubnet, + destSubnet, + nativeTokenSource, + emptySourceFeeInfo, + ) + + checkCollateralEvent( + destChainReceipt.Logs, + nativeTokenDestination, + valueToSend, + big.NewInt(0).Sub(initialReserveImbalance, valueToSend), + ) + checkReserveImbalance( + big.NewInt(0).Sub(initialReserveImbalance, valueToSend), + nativeTokenDestination, + ) + + _, err = utils.GetEventFromLogs( + destChainReceipt.Logs, + nativeTokenDestination.ParseNativeTokensMinted, + ) + Expect(err).ShouldNot(BeNil()) + + // Check intermediate balance, no tokens should be minted because we haven't collateralized + utils.CheckBalance(ctx, tokenReceiverAddress, common.Big0, destSubnet.WSClient) + } + + { + // Fail to Transfer tokens B -> A because bridge is not collateralized + // Check starting balance is 0 + utils.CheckBalance(ctx, tokenReceiverAddress, common.Big0, sourceSubnet.WSClient) + + transactor, err := bind.NewKeyedTransactorWithChainID(deployerPK, destSubnet.EVMChainID) + Expect(err).Should(BeNil()) + transactor.Value = valueToSend + + // This transfer should revert because the bridge isn't collateralized + _, err = nativeTokenDestination.TransferToSource( + transactor, + tokenReceiverAddress, + emptyDestFeeInfo, + []common.Address{}, + ) + Expect(err).ShouldNot(BeNil()) + + // Check we should fail to send because we're not collateralized + utils.CheckBalance(ctx, tokenReceiverAddress, common.Big0, sourceSubnet.WSClient) + } + + { + // Transfer more tokens A -> B to collateralize the bridge + // Check starting balance is 0 + utils.CheckBalance(ctx, tokenReceiverAddress, common.Big0, destSubnet.WSClient) + checkReserveImbalance( + big.NewInt(0).Sub(initialReserveImbalance, valueToSend), + nativeTokenDestination, + ) + + destChainReceipt := sendNativeTokensToDestination( + ctx, + network, + initialReserveImbalance, + deployerPK, + tokenReceiverAddress, + sourceSubnet, + destSubnet, + nativeTokenSource, + emptySourceFeeInfo, + ) + + checkCollateralEvent( + destChainReceipt.Logs, + nativeTokenDestination, + big.NewInt(0).Sub(initialReserveImbalance, valueToSend), + common.Big0, + ) + checkMintEvent( + destChainReceipt.Logs, + nativeTokenDestination, + tokenReceiverAddress, + valueToSend, + ) + checkReserveImbalance(common.Big0, nativeTokenDestination) + + // We should have minted the excess coins after checking the collateral + utils.CheckBalance(ctx, tokenReceiverAddress, valueToSend, destSubnet.WSClient) + } + + { + // Transfer tokens B -> A + sourceChainReceipt := + sendTokensToSource( + ctx, + network, + valueToReturn, + deployerPK, + tokenReceiverAddress, + sourceSubnet, + destSubnet, + nativeTokenDestination, + emptyDestFeeInfo, + ) + + checkUnlockNativeEvent( + sourceChainReceipt.Logs, + nativeTokenSource, + tokenReceiverAddress, + valueToReturn, + ) + + utils.CheckBalance(ctx, tokenReceiverAddress, valueToReturn, sourceSubnet.WSClient) + } + + { + // Check reporting of burned tx fees to Source Chain + burnedTxFeesBalanceDest, err := destSubnet.WSClient.BalanceAt( + ctx, + burnedTxFeeAddress, + nil, + ) + Expect(err).Should(BeNil()) + Expect(burnedTxFeesBalanceDest.Cmp(common.Big0) > 0).Should(BeTrue()) + + transactor, err := bind.NewKeyedTransactorWithChainID(deployerPK, destSubnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := nativeTokenDestination.ReportTotalBurnedTxFees( + transactor, + emptyDestFeeInfo, + []common.Address{}, + ) + Expect(err).Should(BeNil()) + + destChainReceipt := utils.WaitForTransactionSuccess(ctx, tx.Hash(), destSubnet) + + reportEvent, err := utils.GetEventFromLogs( + destChainReceipt.Logs, + nativeTokenDestination.ParseReportTotalBurnedTxFees, + ) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(reportEvent.BurnAddressBalance, burnedTxFeesBalanceDest) + + burnedTxFeesBalanceSource, err := sourceSubnet.WSClient.BalanceAt( + ctx, + burnedTxFeeAddress, + nil, + ) + Expect(err).Should(BeNil()) + Expect(burnedTxFeesBalanceSource.Cmp(common.Big0) > 0).Should(BeTrue()) + + sourceChainReceipt := network.RelayMessage(ctx, destChainReceipt, destSubnet, sourceSubnet, true) + + burnEvent, err := utils.GetEventFromLogs( + sourceChainReceipt.Logs, + nativeTokenSource.ParseBurnTokens, + ) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(burnedTxFeesBalanceDest, burnEvent.Amount) + + burnedTxFeesBalanceSource2, err := sourceSubnet.WSClient.BalanceAt( + ctx, + burnedTxFeeAddress, + nil, + ) + Expect(err).Should(BeNil()) + Expect( + burnedTxFeesBalanceSource2.Cmp( + big.NewInt(0).Add(burnedTxFeesBalanceSource, burnEvent.Amount), + ) >= 0, + ).Should(BeTrue()) + } +} + +func checkUnlockNativeEvent( + logs []*types.Log, + nativeTokenSource *nativetokensource.NativeTokenSource, + recipient common.Address, + value *big.Int, +) { + unlockEvent, err := utils.GetEventFromLogs(logs, nativeTokenSource.ParseUnlockTokens) + Expect(err).Should(BeNil()) + Expect(unlockEvent.Recipient).Should(Equal(recipient)) + Expect(unlockEvent.Amount.Cmp(value)).Should(BeZero()) +} + +func checkCollateralEvent( + logs []*types.Log, + nativeTokenDestination *nativetokendestination.NativeTokenDestination, + collateralAdded *big.Int, + collateralRemaining *big.Int, +) { + collateralEvent, err := utils.GetEventFromLogs( + logs, + nativeTokenDestination.ParseCollateralAdded, + ) + Expect(err).Should(BeNil()) + Expect(collateralEvent.Amount.Cmp(collateralAdded)).Should(BeZero()) + Expect(collateralEvent.Remaining.Cmp(collateralEvent.Remaining)).Should(BeZero()) +} + +func checkMintEvent( + logs []*types.Log, + nativeTokenDestination *nativetokendestination.NativeTokenDestination, + recipient common.Address, + value *big.Int, +) { + mintEvent, err := utils.GetEventFromLogs(logs, nativeTokenDestination.ParseNativeTokensMinted) + Expect(err).Should(BeNil()) + Expect(mintEvent.Recipient).Should(Equal(recipient)) + Expect(mintEvent.Amount.Cmp(value)).Should(BeZero()) +} + +func checkReserveImbalance( + value *big.Int, + nativeTokenDestination *nativetokendestination.NativeTokenDestination, +) { + imbalance, err := nativeTokenDestination.CurrentReserveImbalance(&bind.CallOpts{}) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(imbalance, value) +} + +func sendTokensToSource( + ctx context.Context, + network interfaces.LocalNetwork, + valueToSend *big.Int, + fromKey *ecdsa.PrivateKey, + toAddress common.Address, + sourceSubnet interfaces.SubnetTestInfo, + destinationSubnet interfaces.SubnetTestInfo, + nativeTokenDestination *nativetokendestination.NativeTokenDestination, + feeInfo nativetokendestination.TeleporterFeeInfo, +) *types.Receipt { + transactor, err := bind.NewKeyedTransactorWithChainID(fromKey, destinationSubnet.EVMChainID) + Expect(err).Should(BeNil()) + transactor.Value = valueToSend + + tx, err := nativeTokenDestination.TransferToSource( + transactor, + toAddress, + feeInfo, + []common.Address{}, + ) + Expect(err).Should(BeNil()) + + destChainReceipt := utils.WaitForTransactionSuccess(ctx, tx.Hash(), destinationSubnet) + + transferEvent, err := utils.GetEventFromLogs( + destChainReceipt.Logs, + nativeTokenDestination.ParseTransferToSource, + ) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(transferEvent.Amount, valueToSend) + + receipt := network.RelayMessage(ctx, destChainReceipt, destinationSubnet, sourceSubnet, true) + + return receipt +} + +func sendNativeTokensToDestination( + ctx context.Context, + network interfaces.LocalNetwork, + valueToSend *big.Int, + fromKey *ecdsa.PrivateKey, + toAddress common.Address, + sourceSubnet interfaces.SubnetTestInfo, + destinationSubnet interfaces.SubnetTestInfo, + nativeTokenSource *nativetokensource.NativeTokenSource, + feeInfo nativetokensource.TeleporterFeeInfo, +) *types.Receipt { + transactor, err := bind.NewKeyedTransactorWithChainID(fromKey, sourceSubnet.EVMChainID) + Expect(err).Should(BeNil()) + transactor.Value = valueToSend + + tx, err := nativeTokenSource.TransferToDestination( + transactor, + toAddress, + feeInfo, + []common.Address{}, + ) + Expect(err).Should(BeNil()) + + sourceChainReceipt := utils.WaitForTransactionSuccess(ctx, tx.Hash(), sourceSubnet) + + transferEvent, err := utils.GetEventFromLogs( + sourceChainReceipt.Logs, + nativeTokenSource.ParseTransferToDestination, + ) + Expect(err).Should(BeNil()) + utils.ExpectBigEqual(transferEvent.Amount, valueToSend) + + receipt := network.RelayMessage(ctx, sourceChainReceipt, sourceSubnet, destinationSubnet, true) + + return receipt +} diff --git a/tests/local/e2e_test.go b/tests/local/e2e_test.go index a27395764..b1aeb7379 100644 --- a/tests/local/e2e_test.go +++ b/tests/local/e2e_test.go @@ -57,6 +57,12 @@ var _ = ginkgo.AfterSuite(func() { var _ = ginkgo.Describe("[Teleporter integration tests]", func() { // Cross-chain application tests + ginkgo.It("Send native tokens from subnet A to B and back", func() { + flows.NativeTokenBridge(localNetworkInstance) + }) + ginkgo.It("Send ERC20 tokens from subnet A to Native tokens on subnet B and back", func() { + flows.ERC20ToNativeTokenBridge(localNetworkInstance) + }) ginkgo.It("Example cross chain messenger", func() { flows.ExampleMessenger(localNetworkInstance) }) diff --git a/tests/utils/utils.go b/tests/utils/utils.go index b1683cda1..ed7eb624f 100644 --- a/tests/utils/utils.go +++ b/tests/utils/utils.go @@ -6,27 +6,34 @@ package utils import ( "context" "crypto/ecdsa" + "encoding/json" "fmt" "math/big" "strconv" "strings" "time" + exampleerc20 "github.com/ava-labs/teleporter/abi-bindings/go/Mocks/ExampleERC20" + teleportermessenger "github.com/ava-labs/teleporter/abi-bindings/go/Teleporter/TeleporterMessenger" + deploymentUtils "github.com/ava-labs/teleporter/utils/deployment-utils" + gasUtils "github.com/ava-labs/teleporter/utils/gas-utils" + "github.com/ava-labs/avalanchego/ids" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" + "github.com/ava-labs/subnet-evm/accounts/abi" "github.com/ava-labs/subnet-evm/accounts/abi/bind" "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/eth/tracers" + "github.com/ava-labs/subnet-evm/ethclient" "github.com/ava-labs/subnet-evm/params" predicateutils "github.com/ava-labs/subnet-evm/predicate" + "github.com/ava-labs/subnet-evm/rpc" "github.com/ava-labs/subnet-evm/x/warp" erc20bridge "github.com/ava-labs/teleporter/abi-bindings/go/CrossChainApplications/ERC20Bridge/ERC20Bridge" examplecrosschainmessenger "github.com/ava-labs/teleporter/abi-bindings/go/CrossChainApplications/ExampleMessenger/ExampleCrossChainMessenger" blockhashpublisher "github.com/ava-labs/teleporter/abi-bindings/go/CrossChainApplications/VerifiedBlockHash/BlockHashPublisher" blockhashreceiver "github.com/ava-labs/teleporter/abi-bindings/go/CrossChainApplications/VerifiedBlockHash/BlockHashReceiver" - exampleerc20 "github.com/ava-labs/teleporter/abi-bindings/go/Mocks/ExampleERC20" - teleportermessenger "github.com/ava-labs/teleporter/abi-bindings/go/Teleporter/TeleporterMessenger" "github.com/ava-labs/teleporter/tests/interfaces" - gasUtils "github.com/ava-labs/teleporter/utils/gas-utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" @@ -281,11 +288,10 @@ func CreateSendCrossChainMessageTransaction( senderKey *ecdsa.PrivateKey, teleporterContractAddress common.Address, ) *types.Transaction { - fundedAddress := crypto.PubkeyToAddress(senderKey.PublicKey) data, err := teleportermessenger.PackSendCrossChainMessage(input) Expect(err).Should(BeNil()) - gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, source, fundedAddress) + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, source, PrivateKeyToAddress(senderKey)) // Send a transaction to the Teleporter contract tx := types.NewTx(&types.DynamicFeeTx{ @@ -310,8 +316,6 @@ func CreateRetryMessageExecutionTransaction( senderKey *ecdsa.PrivateKey, teleporterContractAddress common.Address, ) *types.Transaction { - fundedAddress := crypto.PubkeyToAddress(senderKey.PublicKey) - data, err := teleportermessenger.PackRetryMessageExecution(originChainID, message) Expect(err).Should(BeNil()) @@ -319,7 +323,7 @@ func CreateRetryMessageExecutionTransaction( gasLimit, err := gasUtils.CalculateReceiveMessageGasLimit(10, message.RequiredGasLimit) Expect(err).Should(BeNil()) - gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, fundedAddress) + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, PrivateKeyToAddress(senderKey)) // Sign a transaction to the Teleporter contract tx := types.NewTx(&types.DynamicFeeTx{ @@ -346,7 +350,6 @@ func CreateReceiveCrossChainMessageTransaction( senderKey *ecdsa.PrivateKey, subnetInfo interfaces.SubnetTestInfo, ) *types.Transaction { - fundedAddress := crypto.PubkeyToAddress(senderKey.PublicKey) // Construct the transaction to send the Warp message to the destination chain log.Info("Constructing transaction for the destination chain") signedMessage, err := avalancheWarp.ParseMessage(warpMessageBytes) @@ -358,10 +361,10 @@ func CreateReceiveCrossChainMessageTransaction( gasLimit, err := gasUtils.CalculateReceiveMessageGasLimit(numSigners, requiredGasLimit) Expect(err).Should(BeNil()) - callData, err := teleportermessenger.PackReceiveCrossChainMessage(0, fundedAddress) + callData, err := teleportermessenger.PackReceiveCrossChainMessage(0, PrivateKeyToAddress(senderKey)) Expect(err).Should(BeNil()) - gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, fundedAddress) + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, PrivateKeyToAddress(senderKey)) destinationTx := predicateutils.NewPredicateTx( subnetInfo.EVMChainID, @@ -403,6 +406,16 @@ func CreateNativeTransferTransaction( return SignTransaction(tx, fromKey, subnetInfo.EVMChainID) } +func WaitForTransactionSuccess( + ctx context.Context, + txHash common.Hash, + subnetInfo interfaces.SubnetTestInfo, +) *types.Receipt { + receipt := WaitForTransaction(ctx, txHash, subnetInfo) + Expect(receipt.Status).Should(Equal(types.ReceiptStatusSuccessful)) + return receipt +} + func WaitForTransaction(ctx context.Context, txHash common.Hash, subnetInfo interfaces.SubnetTestInfo) *types.Receipt { cctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() @@ -413,16 +426,13 @@ func WaitForTransaction(ctx context.Context, txHash common.Hash, subnetInfo inte if err == nil { return receipt } else { + Expect(err).ShouldNot(Equal(context.DeadlineExceeded)) log.Info("Waiting for transaction", "hash", txHash.Hex()) - time.Sleep(200 * time.Millisecond) + time.Sleep(500 * time.Millisecond) } } } -// -// Event getters -// - // Returns the first log in 'logs' that is successfully parsed by 'parser' func GetEventFromLogs[T any](logs []*types.Log, parser func(log types.Log) (T, error)) (T, error) { for _, log := range logs { @@ -434,10 +444,6 @@ func GetEventFromLogs[T any](logs []*types.Log, parser func(log types.Log) (T, e return *new(T), fmt.Errorf("failed to find %T event in receipt logs", *new(T)) } -// -// Unexported functions -// - // Signs a transaction using the provided key for the specified chainID func SignTransaction(tx *types.Transaction, key *ecdsa.PrivateKey, chainID *big.Int) *types.Transaction { txSigner := types.LatestSignerForChainID(chainID) @@ -468,6 +474,78 @@ func CalculateTxParams( return gasFeeCap, gasTipCap, nonce } +func PrivateKeyToAddress(k *ecdsa.PrivateKey) common.Address { + return crypto.PubkeyToAddress(k.PublicKey) +} + +// Throws a Gomega error if there is a mismatch +func CheckBalance(ctx context.Context, addr common.Address, expectedBalance *big.Int, wsClient ethclient.Client) { + bal, err := wsClient.BalanceAt(ctx, addr, nil) + Expect(err).Should(BeNil()) + ExpectBigEqual(bal, expectedBalance) +} + +func TraceTransaction(ctx context.Context, txHash common.Hash, subnetInfo interfaces.SubnetTestInfo) string { + url := HttpToRPCURI(subnetInfo.NodeURIs[0], subnetInfo.BlockchainID.String()) + rpcClient, err := rpc.DialContext(ctx, url) + Expect(err).Should(BeNil()) + defer rpcClient.Close() + + var result interface{} + ct := "callTracer" + err = rpcClient.Call(&result, "debug_traceTransaction", txHash.String(), tracers.TraceConfig{Tracer: &ct}) + Expect(err).Should(BeNil()) + + jsonStr, err := json.Marshal(result) + Expect(err).Should(BeNil()) + + return string(jsonStr) +} + +func DeployContract( + ctx context.Context, + byteCodeFileName string, + deployerPK *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, + abi *abi.ABI, + constructorArgs ...interface{}, +) { + // Deploy an example ERC20 contract to be used as the source token + byteCode, err := deploymentUtils.ExtractByteCode(byteCodeFileName) + Expect(err).Should(BeNil()) + Expect(len(byteCode) > 0).Should(BeTrue()) + transactor, err := bind.NewKeyedTransactorWithChainID(deployerPK, subnetInfo.EVMChainID) + Expect(err).Should(BeNil()) + contractAddress, tx, _, err := bind.DeployContract( + transactor, + *abi, + byteCode, + subnetInfo.WSClient, + constructorArgs..., + ) + Expect(err).Should(BeNil()) + + // Wait for transaction, then check code was deployed + receipt := WaitForTransaction(ctx, tx.Hash(), subnetInfo) + Expect(receipt.Status).Should(Equal(types.ReceiptStatusSuccessful)) + code, err := subnetInfo.WSClient.CodeAt(ctx, contractAddress, nil) + Expect(err).Should(BeNil()) + Expect(len(code)).Should(BeNumerically(">", 2)) // 0x is an EOA, contract returns the bytecode +} + +func ExpectBigEqual(v1 *big.Int, v2 *big.Int) { + // Compare strings, so gomega will print the numbers if they differ + Expect(v1.String()).Should(Equal(v2.String())) +} + +func BigIntSub(v1 *big.Int, v2 *big.Int) *big.Int { + return big.NewInt(0).Sub(v1, v2) +} + +func BigIntMul(v1 *big.Int, v2 *big.Int) *big.Int { + return big.NewInt(0).Mul(v1, v2) +} + func ERC20Approve( ctx context.Context, token *exampleerc20.ExampleERC20, diff --git a/tests/utils/warp-genesis.json b/tests/utils/warp-genesis.json index a9d402e66..012b048fc 100644 --- a/tests/utils/warp-genesis.json +++ b/tests/utils/warp-genesis.json @@ -25,16 +25,23 @@ }, "warpConfig": { "blockTimestamp": 0 + }, + "contractNativeMinterConfig": { + "blockTimestamp": 0, + "adminAddresses": [ + "0xAcB633F5B00099c7ec187eB00156c5cd9D854b5B", + "0x3405506b3711859c5070949ed9b700c7ba7bf750" + ] } }, "alloc": { "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC": { "balance": "0x52B7D2DCC80CD2E4000000" }, - "0x0Fa8EA536Be85F32724D57A37758761B86416123": { + "0x1337cfd2dCff6270615B90938aCB1efE79801704": { "balance": "0x52B7D2DCC80CD2E4000000" }, - "0x1dD31B5351e76d51F4B152ce64fE5cf594694De5": { + "0x539447ab8Be7e927bE8E005663C81ff2AE951337": { "balance": "0x52B7D2DCC80CD2E4000000" } }, diff --git a/utils/deployment-utils/deployment_utils.go b/utils/deployment-utils/deployment_utils.go index 0263c030d..43d18ebd2 100644 --- a/utils/deployment-utils/deployment_utils.go +++ b/utils/deployment-utils/deployment_utils.go @@ -31,7 +31,9 @@ const ( ) var ( - vValue = big.NewInt(27) // Must be less than 35 to be considered non-EIP155 + vValue = big.NewInt( + 27, + ) // Must be less than 35 to be considered non-EIP155 contractCreationGasPrice = big.NewInt(2500000000000) // 2500 nAVAX/gas ) @@ -86,12 +88,16 @@ func ExtractByteCode(byteCodeFileName string) ([]byte, error) { // Constructs a keyless transaction using Nick's method // Optionally writes the transaction, deployer address, and contract address to file // Returns the transaction bytes, deployer address, and contract address -func ConstructKeylessTransaction(byteCodeFileName string, - writeFile bool) ([]byte, common.Address, common.Address, error) { +func ConstructKeylessTransaction( + byteCodeFileName string, + writeFile bool, +) ([]byte, common.Address, common.Address, error) { // Convert the R and S values (which must be the same) from hex. rsValue, ok := new(big.Int).SetString(rsValueHex, 16) if !ok { - return nil, common.Address{}, common.Address{}, errors.New("Failed to convert R and S value to big.Int.") + return nil, common.Address{}, common.Address{}, errors.New( + "Failed to convert R and S value to big.Int.", + ) } byteCode, err := ExtractByteCode(byteCodeFileName) @@ -115,13 +121,19 @@ func ConstructKeylessTransaction(byteCodeFileName string, // Recover the "sender" address of the transaction. senderAddress, err := types.HomesteadSigner{}.Sender(contractCreationTx) if err != nil { - return nil, common.Address{}, common.Address{}, errors.Wrap(err, "Failed to recover the transaction sender address") + return nil, common.Address{}, common.Address{}, errors.Wrap( + err, + "Failed to recover the sender address of transaction", + ) } // Serialize the raw transaction and sender address. contractCreationTxBytes, err := contractCreationTx.MarshalBinary() if err != nil { - return nil, common.Address{}, common.Address{}, errors.Wrap(err, "Failed to serialize raw transaction") + return nil, common.Address{}, common.Address{}, errors.Wrap( + err, + "Failed to serialize raw transaction", + ) } contractCreationTxString := "0x" + hex.EncodeToString(contractCreationTxBytes) senderAddressString := senderAddress.Hex() // "0x" prepended by Hex() already. @@ -129,7 +141,10 @@ func ConstructKeylessTransaction(byteCodeFileName string, // Derive the resulting contract address given that it will be deployed from the sender address using the nonce of 0. contractAddress, err := DeriveEVMContractAddress(senderAddress, 0) if err != nil { - return nil, common.Address{}, common.Address{}, errors.Wrap(err, "Failed to derive contract address") + return nil, common.Address{}, common.Address{}, errors.Wrap( + err, + "Failed to derive contract address", + ) } contractAddressString := contractAddress.Hex() // "0x" prepended by Hex() already. @@ -139,19 +154,36 @@ func ConstructKeylessTransaction(byteCodeFileName string, log.Println("Teleporter Messenger Universal Contract Address: ", contractAddressString) if writeFile { - err = os.WriteFile(contractCreationTxFileName, []byte(contractCreationTxString), fs.ModePerm) + err = os.WriteFile( + contractCreationTxFileName, + []byte(contractCreationTxString), + fs.ModePerm, + ) if err != nil { - return nil, common.Address{}, common.Address{}, errors.Wrap(err, "Failed to write to contract creation tx file") + return nil, common.Address{}, common.Address{}, errors.Wrap( + err, + "Failed to write to contract creation tx file", + ) } err = os.WriteFile(contractCreationAddrFileName, []byte(senderAddressString), fs.ModePerm) if err != nil { - return nil, common.Address{}, common.Address{}, errors.Wrap(err, "Failed to write to deployer address file") + return nil, common.Address{}, common.Address{}, errors.Wrap( + err, + "Failed to write to deployer address file", + ) } - err = os.WriteFile(universalContractAddressFileName, []byte(contractAddressString), fs.ModePerm) + err = os.WriteFile( + universalContractAddressFileName, + []byte(contractAddressString), + fs.ModePerm, + ) if err != nil { - return nil, common.Address{}, common.Address{}, errors.Wrap(err, "Failed to write to contract address") + return nil, common.Address{}, common.Address{}, errors.Wrap( + err, + "Failed to write to contract address", + ) } } return contractCreationTxBytes, senderAddress, contractAddress, nil