From 4522ea2840a01c1d0e10c1f59a1d6d3ac1d9a6a2 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Fri, 31 May 2024 18:32:55 -0400 Subject: [PATCH 01/46] feat: wip ulxly util --- bindings/ulxly/PolygonZkEVMBridgeV2.abi | 1004 ++++++++++++ bindings/ulxly/PolygonZkEVMBridgeV2.bin | 1 + bindings/ulxly/PolygonZkEVMBridgeV2.go | 1935 +++++++++++++++++++++++ cmd/root.go | 2 + cmd/ulxly/ulxly.go | 95 ++ contracts/Makefile | 8 + 6 files changed, 3045 insertions(+) create mode 100644 bindings/ulxly/PolygonZkEVMBridgeV2.abi create mode 100644 bindings/ulxly/PolygonZkEVMBridgeV2.bin create mode 100644 bindings/ulxly/PolygonZkEVMBridgeV2.go create mode 100644 cmd/ulxly/ulxly.go diff --git a/bindings/ulxly/PolygonZkEVMBridgeV2.abi b/bindings/ulxly/PolygonZkEVMBridgeV2.abi new file mode 100644 index 00000000..51d9e1fe --- /dev/null +++ b/bindings/ulxly/PolygonZkEVMBridgeV2.abi @@ -0,0 +1,1004 @@ +[ + { + "type": "constructor", + "inputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "BASE_INIT_BYTECODE_WRAPPED_TOKEN", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "WETHToken", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract TokenWrapped" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "activateEmergencyState", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "bridgeAsset", + "inputs": [ + { + "name": "destinationNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "destinationAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "forceUpdateGlobalExitRoot", + "type": "bool", + "internalType": "bool" + }, + { + "name": "permitData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "bridgeMessage", + "inputs": [ + { + "name": "destinationNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "destinationAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "forceUpdateGlobalExitRoot", + "type": "bool", + "internalType": "bool" + }, + { + "name": "metadata", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "bridgeMessageWETH", + "inputs": [ + { + "name": "destinationNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "destinationAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "amountWETH", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "forceUpdateGlobalExitRoot", + "type": "bool", + "internalType": "bool" + }, + { + "name": "metadata", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "calculateRoot", + "inputs": [ + { + "name": "leafHash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "smtProof", + "type": "bytes32[32]", + "internalType": "bytes32[32]" + }, + { + "name": "index", + "type": "uint32", + "internalType": "uint32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "calculateTokenWrapperAddress", + "inputs": [ + { + "name": "originNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originTokenAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "claimAsset", + "inputs": [ + { + "name": "smtProofLocalExitRoot", + "type": "bytes32[32]", + "internalType": "bytes32[32]" + }, + { + "name": "smtProofRollupExitRoot", + "type": "bytes32[32]", + "internalType": "bytes32[32]" + }, + { + "name": "globalIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "mainnetExitRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "rollupExitRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "originNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originTokenAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "destinationNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "destinationAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "metadata", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimMessage", + "inputs": [ + { + "name": "smtProofLocalExitRoot", + "type": "bytes32[32]", + "internalType": "bytes32[32]" + }, + { + "name": "smtProofRollupExitRoot", + "type": "bytes32[32]", + "internalType": "bytes32[32]" + }, + { + "name": "globalIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "mainnetExitRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "rollupExitRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "originNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "destinationNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "destinationAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "metadata", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimedBitMap", + "inputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "deactivateEmergencyState", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "depositCount", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "gasTokenAddress", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "gasTokenMetadata", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "gasTokenNetwork", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint32", + "internalType": "uint32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getLeafValue", + "inputs": [ + { + "name": "leafType", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "originNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "destinationNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "destinationAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "metadataHash", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "getRoot", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getTokenMetadata", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getTokenWrappedAddress", + "inputs": [ + { + "name": "originNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originTokenAddress", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "globalExitRootManager", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IBasePolygonZkEVMGlobalExitRoot" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "_networkID", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "_gasTokenAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "_gasTokenNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "_globalExitRootManager", + "type": "address", + "internalType": "contract IBasePolygonZkEVMGlobalExitRoot" + }, + { + "name": "_polygonRollupManager", + "type": "address", + "internalType": "address" + }, + { + "name": "_gasTokenMetadata", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "isClaimed", + "inputs": [ + { + "name": "leafIndex", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "sourceBridgeNetwork", + "type": "uint32", + "internalType": "uint32" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isEmergencyState", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "lastUpdatedDepositCount", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint32", + "internalType": "uint32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "networkID", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint32", + "internalType": "uint32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "polygonRollupManager", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "precalculatedWrapperAddress", + "inputs": [ + { + "name": "originNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originTokenAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "name", + "type": "string", + "internalType": "string" + }, + { + "name": "symbol", + "type": "string", + "internalType": "string" + }, + { + "name": "decimals", + "type": "uint8", + "internalType": "uint8" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "tokenInfoToWrappedToken", + "inputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "updateGlobalExitRoot", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "verifyMerkleProof", + "inputs": [ + { + "name": "leafHash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "smtProof", + "type": "bytes32[32]", + "internalType": "bytes32[32]" + }, + { + "name": "index", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "root", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "wrappedTokenToTokenInfo", + "inputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "originNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originTokenAddress", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "BridgeEvent", + "inputs": [ + { + "name": "leafType", + "type": "uint8", + "indexed": false, + "internalType": "uint8" + }, + { + "name": "originNetwork", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + }, + { + "name": "originAddress", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "destinationNetwork", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + }, + { + "name": "destinationAddress", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "metadata", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + }, + { + "name": "depositCount", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ClaimEvent", + "inputs": [ + { + "name": "globalIndex", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "originNetwork", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + }, + { + "name": "originAddress", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "destinationAddress", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EmergencyStateActivated", + "inputs": [], + "anonymous": false + }, + { + "type": "event", + "name": "EmergencyStateDeactivated", + "inputs": [], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint8", + "indexed": false, + "internalType": "uint8" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NewWrappedToken", + "inputs": [ + { + "name": "originNetwork", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + }, + { + "name": "originTokenAddress", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "wrappedTokenAddress", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "metadata", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AlreadyClaimed", + "inputs": [] + }, + { + "type": "error", + "name": "AmountDoesNotMatchMsgValue", + "inputs": [] + }, + { + "type": "error", + "name": "DestinationNetworkInvalid", + "inputs": [] + }, + { + "type": "error", + "name": "EtherTransferFailed", + "inputs": [] + }, + { + "type": "error", + "name": "FailedTokenWrappedDeployment", + "inputs": [] + }, + { + "type": "error", + "name": "GasTokenNetworkMustBeZeroOnEther", + "inputs": [] + }, + { + "type": "error", + "name": "GlobalExitRootInvalid", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidSmtProof", + "inputs": [] + }, + { + "type": "error", + "name": "MerkleTreeFull", + "inputs": [] + }, + { + "type": "error", + "name": "MessageFailed", + "inputs": [] + }, + { + "type": "error", + "name": "MsgValueNotZero", + "inputs": [] + }, + { + "type": "error", + "name": "NativeTokenIsEther", + "inputs": [] + }, + { + "type": "error", + "name": "NoValueInMessagesOnGasTokenNetworks", + "inputs": [] + }, + { + "type": "error", + "name": "NotValidAmount", + "inputs": [] + }, + { + "type": "error", + "name": "NotValidOwner", + "inputs": [] + }, + { + "type": "error", + "name": "NotValidSignature", + "inputs": [] + }, + { + "type": "error", + "name": "NotValidSpender", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyEmergencyState", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyNotEmergencyState", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyRollupManager", + "inputs": [] + } +] diff --git a/bindings/ulxly/PolygonZkEVMBridgeV2.bin b/bindings/ulxly/PolygonZkEVMBridgeV2.bin new file mode 100644 index 00000000..0ad3409f --- /dev/null +++ b/bindings/ulxly/PolygonZkEVMBridgeV2.bin @@ -0,0 +1 @@ +0x60806040523480156200001157600080fd5b506200001c62000022565b620000e4565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e2576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61565c80620000f46000396000f3fe6080604052600436106101e35760003560e01c806383f2440311610102578063ccaa2d1111610095578063ee25560b11610064578063ee25560b146105cc578063f5efcd79146105f9578063f811bff714610619578063fb5708341461063957600080fd5b8063ccaa2d111461055d578063cd5865791461057d578063d02103ca14610590578063dbc16976146105b757600080fd5b8063bab161bf116100d1578063bab161bf146104d7578063be5831c7146104f9578063c00f14ab1461051d578063cc4616321461053d57600080fd5b806383f24403146104575780638ed7e3f214610477578063aaa13cc214610497578063b8b284d0146104b757600080fd5b80633cbc795b1161017a5780637843298b116101495780637843298b146103d757806379e2cf97146103f757806381b1c1741461040c57806383c43a551461044257600080fd5b80633cbc795b146103495780633e197043146103825780634b2f336d146103a25780635ca1e165146103c257600080fd5b806327aef4e8116101b657806327aef4e8146102795780632dfdf0b51461029b578063318aee3d146102bf5780633c351e101461032957600080fd5b806315064c96146101e85780632072f6c51461021757806322e95f2c1461022e578063240ff37814610266575b600080fd5b3480156101f457600080fd5b506068546102029060ff1681565b60405190151581526020015b60405180910390f35b34801561022357600080fd5b5061022c610659565b005b34801561023a57600080fd5b5061024e610249366004612c00565b61068e565b6040516001600160a01b03909116815260200161020e565b61022c610274366004612c8e565b6106df565b34801561028557600080fd5b5061028e61074f565b60405161020e9190612d58565b3480156102a757600080fd5b506102b160535481565b60405190815260200161020e565b3480156102cb57600080fd5b506103056102da366004612d72565b606b6020526000908152604090205463ffffffff81169064010000000090046001600160a01b031682565b6040805163ffffffff90931683526001600160a01b0390911660208301520161020e565b34801561033557600080fd5b50606d5461024e906001600160a01b031681565b34801561035557600080fd5b50606d5461036d90600160a01b900463ffffffff1681565b60405163ffffffff909116815260200161020e565b34801561038e57600080fd5b506102b161039d366004612d9e565b6107dd565b3480156103ae57600080fd5b50606f5461024e906001600160a01b031681565b3480156103ce57600080fd5b506102b161086a565b3480156103e357600080fd5b5061024e6103f2366004612e1d565b610947565b34801561040357600080fd5b5061022c610971565b34801561041857600080fd5b5061024e610427366004612e66565b606a602052600090815260409020546001600160a01b031681565b34801561044e57600080fd5b5061028e610992565b34801561046357600080fd5b506102b1610472366004612e91565b6109b1565b34801561048357600080fd5b50606c5461024e906001600160a01b031681565b3480156104a357600080fd5b5061024e6104b2366004612f9d565b610a87565b3480156104c357600080fd5b5061022c6104d2366004613039565b610b89565b3480156104e357600080fd5b5060685461036d90610100900463ffffffff1681565b34801561050557600080fd5b5060685461036d90600160c81b900463ffffffff1681565b34801561052957600080fd5b5061028e610538366004612d72565b610c50565b34801561054957600080fd5b506102026105583660046130bc565b610c95565b34801561056957600080fd5b5061022c6105783660046130ef565b610d1f565b61022c61058b3660046131db565b611238565b34801561059c57600080fd5b5060685461024e90600160281b90046001600160a01b031681565b3480156105c357600080fd5b5061022c611689565b3480156105d857600080fd5b506102b16105e7366004612e66565b60696020526000908152604090205481565b34801561060557600080fd5b5061022c6106143660046130ef565b6116bc565b34801561062557600080fd5b5061022c610634366004613271565b611976565b34801561064557600080fd5b5061020261065436600461331a565b611be9565b606c546001600160a01b0316331461068457604051631736745960e31b815260040160405180910390fd5b61068c611c01565b565b6000606a600084846040516020016106a7929190613362565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b031690505b92915050565b60685460ff161561070357604051630bc011ff60e21b815260040160405180910390fd5b341580159061071c5750606f546001600160a01b031615155b1561073a576040516301bd897160e61b815260040160405180910390fd5b610748858534868686611c5d565b5050505050565b606e805461075c9061338c565b80601f01602080910402602001604051908101604052809291908181526020018280546107889061338c565b80156107d55780601f106107aa576101008083540402835291602001916107d5565b820191906000526020600020905b8154815290600101906020018083116107b857829003601f168201915b505050505081565b6040516001600160f81b031960f889901b1660208201526001600160e01b031960e088811b821660218401526001600160601b0319606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b605354600090819081805b602081101561093e578083901c6001166001036108d2576033816020811061089f5761089f6133c6565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506108ff565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b60408051602081018490529081018390526060016040516020818303038152906040528051906020012091508080610936906133f2565b915050610875565b50919392505050565b6000610969848461095785611d27565b61096086611de6565b6104b287611e9e565b949350505050565b605354606854600160c81b900463ffffffff16101561068c5761068c611f56565b60405180611ba00160405280611b668152602001613ac1611b66913981565b600083815b6020811015610a7e57600163ffffffff8516821c81169003610a21578481602081106109e4576109e46133c6565b602002013582604051602001610a04929190918252602082015260400190565b604051602081830303815290604052805190602001209150610a6c565b81858260208110610a3457610a346133c6565b6020020135604051602001610a53929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b80610a76816133f2565b9150506109b6565b50949350505050565b6000808686604051602001610a9d929190613362565b604051602081830303815290604052805190602001209050600060ff60f81b308360405180611ba00160405280611b668152602001613ac1611b669139898989604051602001610aef9392919061340b565b60408051601f1981840301815290829052610b0d9291602001613444565b60405160208183030381529060405280519060200120604051602001610b6594939291906001600160f81b031994909416845260609290921b6001600160601b03191660018401526015830152603582015260550190565b60408051808303601f19018152919052805160209091012098975050505050505050565b60685460ff1615610bad57604051630bc011ff60e21b815260040160405180910390fd5b606f546001600160a01b0316610bd65760405163dde3cda760e01b815260040160405180910390fd5b606f54604051632770a7eb60e21b8152336004820152602481018690526001600160a01b0390911690639dc29fac90604401600060405180830381600087803b158015610c2257600080fd5b505af1158015610c36573d6000803e3d6000fd5b50505050610c48868686868686611c5d565b505050505050565b6060610c5b82611d27565b610c6483611de6565b610c6d84611e9e565b604051602001610c7f9392919061340b565b6040516020818303038152906040529050919050565b6068546000908190610100900463ffffffff16158015610cbb575063ffffffff83166001145b15610ccd575063ffffffff8316610cf5565b610ce264010000000063ffffffff8516613473565b610cf29063ffffffff861661348a565b90505b600881901c600090815260696020526040902054600160ff9092169190911b908116149392505050565b60685460ff1615610d4357604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff8681166101009092041614610d73576040516302caf51760e11b815260040160405180910390fd5b610da78c8c8c8c8c610da260008e8e8e8e8e8e8e604051610d9592919061349d565b60405180910390206107dd565b611fef565b6001600160a01b038616610ee157606f546001600160a01b0316610e765760006001600160a01b03851684825b6040519080825280601f01601f191660200182016040528015610dfe576020820181803683370190505b50604051610e0c91906134ad565b60006040518083038185875af1925050503d8060008114610e49576040519150601f19603f3d011682016040523d82523d6000602084013e610e4e565b606091505b5050905080610e7057604051630ce8f45160e31b815260040160405180910390fd5b506111ce565b606f546040516340c10f1960e01b81526001600160a01b03868116600483015260248201869052909116906340c10f1990604401600060405180830381600087803b158015610ec457600080fd5b505af1158015610ed8573d6000803e3d6000fd5b505050506111ce565b606d546001600160a01b038781169116148015610f0f5750606d5463ffffffff888116600160a01b90920416145b15610f275760006001600160a01b0385168482610dd4565b60685463ffffffff610100909104811690881603610f5857610f536001600160a01b0387168585612153565b6111ce565b60008787604051602001610f6d929190613362565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b031680611168576000610fe58386868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506121bb92505050565b6040516340c10f1960e01b81526001600160a01b03898116600483015260248201899052919250908216906340c10f1990604401600060405180830381600087803b15801561103357600080fd5b505af1158015611047573d6000803e3d6000fd5b5050505080606a600085815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060405180604001604052808b63ffffffff1681526020018a6001600160a01b0316815250606b6000836001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398a8a83888860405161115a9594939291906134f2565b60405180910390a1506111cb565b6040516340c10f1960e01b81526001600160a01b038781166004830152602482018790528216906340c10f1990604401600060405180830381600087803b1580156111b257600080fd5b505af11580156111c6573d6000803e3d6000fd5b505050505b50505b604080518b815263ffffffff891660208201526001600160a01b0388811682840152861660608201526080810185905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a1505050505050505050505050565b60685460ff161561125c57604051630bc011ff60e21b815260040160405180910390fd5b611264612237565b60685463ffffffff610100909104811690881603611295576040516302caf51760e11b815260040160405180910390fd5b6000806060876001600160a01b03881661137b578834146112c95760405163b89240f560e01b815260040160405180910390fd5b606d54606e80546001600160a01b0383169650600160a01b90920463ffffffff169450906112f69061338c565b80601f01602080910402602001604051908101604052809291908181526020018280546113229061338c565b801561136f5780601f106113445761010080835404028352916020019161136f565b820191906000526020600020905b81548152906001019060200180831161135257829003601f168201915b505050505091506115fe565b341561139a5760405163798ee6f160e01b815260040160405180910390fd5b606f546001600160a01b039081169089160361141557604051632770a7eb60e21b8152336004820152602481018a90526001600160a01b03891690639dc29fac90604401600060405180830381600087803b1580156113f857600080fd5b505af115801561140c573d6000803e3d6000fd5b505050506115fe565b6001600160a01b038089166000908152606b602090815260409182902082518084019093525463ffffffff81168352640100000000900490921691810182905290156114ce57604051632770a7eb60e21b8152336004820152602481018b90526001600160a01b038a1690639dc29fac90604401600060405180830381600087803b1580156114a357600080fd5b505af11580156114b7573d6000803e3d6000fd5b5050505080602001519450806000015193506115f1565b85156114e0576114e0898b8989612290565b6040516370a0823160e01b81523060048201526000906001600160a01b038b16906370a0823190602401602060405180830381865afa158015611527573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154b919061352b565b90506115626001600160a01b038b1633308e6125d6565b6040516370a0823160e01b81523060048201526000906001600160a01b038c16906370a0823190602401602060405180830381865afa1580156115a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115cd919061352b565b90506115d98282613544565b6068548c9850610100900463ffffffff169650935050505b6115fa89610c50565b9250505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b600084868e8e868860535460405161163e989796959493929190613557565b60405180910390a1611665611660600085878f8f8789805190602001206107dd565b61260e565b861561167357611673611f56565b5050505061168060018055565b50505050505050565b606c546001600160a01b031633146116b457604051631736745960e31b815260040160405180910390fd5b61068c6126f9565b60685460ff16156116e057604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff8681166101009092041614611710576040516302caf51760e11b815260040160405180910390fd5b6117328c8c8c8c8c610da260018e8e8e8e8e8e8e604051610d9592919061349d565b606f546000906001600160a01b03166117e957846001600160a01b031684888a868660405160240161176794939291906135c2565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b1790525161179c91906134ad565b60006040518083038185875af1925050503d80600081146117d9576040519150601f19603f3d011682016040523d82523d6000602084013e6117de565b606091505b5050809150506118ed565b606f546040516340c10f1960e01b81526001600160a01b03878116600483015260248201879052909116906340c10f1990604401600060405180830381600087803b15801561183757600080fd5b505af115801561184b573d6000803e3d6000fd5b50505050846001600160a01b03168789858560405160240161187094939291906135c2565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b179052516118a591906134ad565b6000604051808303816000865af19150503d80600081146118e2576040519150601f19603f3d011682016040523d82523d6000602084013e6118e7565b606091505b50909150505b8061190b576040516337e391c360e01b815260040160405180910390fd5b604080518c815263ffffffff8a1660208201526001600160a01b0389811682840152871660608201526080810186905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a150505050505050505050505050565b600054610100900460ff16158080156119965750600054600160ff909116105b806119b05750303b1580156119b0575060005460ff166001145b611a185760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015611a3b576000805461ff0019166101001790555b60688054610100600160c81b03191661010063ffffffff8a160265010000000000600160c81b03191617600160281b6001600160a01b038781169190910291909117909155606c80546001600160a01b0319168583161790558616611ac45763ffffffff851615611abf57604051630d43a60960e11b815260040160405180910390fd5b611b93565b606d805463ffffffff8716600160a01b026001600160c01b03199091166001600160a01b03891617179055606e611afb8382613643565b50611b726000801b6012604051602001611b5e91906060808252600d908201526c2bb930b83832b21022ba3432b960991b608082015260a060208201819052600490820152630ae8aa8960e31b60c082015260ff91909116604082015260e00190565b6040516020818303038152906040526121bb565b606f80546001600160a01b0319166001600160a01b03929092169190911790555b611b9b612751565b8015611680576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050565b600081611bf78686866109b1565b1495945050505050565b60685460ff1615611c2557604051630bc011ff60e21b815260040160405180910390fd5b6068805460ff191660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a549790600090a1565b60685463ffffffff610100909104811690871603611c8e576040516302caf51760e11b815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff16338989898888605354604051611ce299989796959493929190613703565b60405180910390a1611d196116606001606860019054906101000a900463ffffffff16338a8a8a8989604051610d9592919061349d565b8215610c4857610c48611f56565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b179052905160609160009182916001600160a01b03861691611d6e91906134ad565b600060405180830381855afa9150503d8060008114611da9576040519150601f19603f3d011682016040523d82523d6000602084013e611dae565b606091505b509150915081611ddd57604051806040016040528060078152602001664e4f5f4e414d4560c81b815250610969565b61096981612780565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b179052905160609160009182916001600160a01b03861691611e2d91906134ad565b600060405180830381855afa9150503d8060008114611e68576040519150601f19603f3d011682016040523d82523d6000602084013e611e6d565b606091505b509150915081611ddd57604051806040016040528060098152602001681393d7d4d6535093d360ba1b815250610969565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b03861691611ee491906134ad565b600060405180830381855afa9150503d8060008114611f1f576040519150601f19603f3d011682016040523d82523d6000602084013e611f24565b606091505b5091509150818015611f37575080516020145b611f42576012610969565b808060200190518101906109699190613770565b6053546068805463ffffffff909216600160c81b0263ffffffff60c81b1990921691909117908190556001600160a01b03600160281b909104166333d6247d611f9d61086a565b6040518263ffffffff1660e01b8152600401611fbb91815260200190565b600060405180830381600087803b158015611fd557600080fd5b505af1158015611fe9573d6000803e3d6000fd5b50505050565b606854604080516020808201879052818301869052825180830384018152606083019384905280519101206312bd9b1960e11b9092526064810191909152600091600160281b90046001600160a01b03169063257b3632906084016020604051808303816000875af1158015612069573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208d919061352b565b9050806000036120af57604051622f6fad60e01b815260040160405180910390fd5b600080680100000000000000008716156120f4578691506120d2848a8489611be9565b6120ef576040516338105f3b60e21b815260040160405180910390fd5b61213e565b602087901c61210481600161378d565b915087925061211f612117868c866109b1565b8a8389611be9565b61213c576040516338105f3b60e21b815260040160405180910390fd5b505b612148828261290f565b505050505050505050565b6040516001600160a01b0383166024820152604481018290526121b690849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526129b8565b505050565b60008060405180611ba00160405280611b668152602001613ac1611b669139836040516020016121ec929190613444565b6040516020818303038152906040529050838151602083016000f591506001600160a01b038216612230576040516305f7d84960e51b815260040160405180910390fd5b5092915050565b6002600154036122895760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611a0f565b6002600155565b600061229f60048284866137aa565b6122a8916137d4565b9050632afa533160e01b6001600160e01b031982160161243c5760008080808080806122d7896004818d6137aa565b8101906122e49190613804565b9650965096509650965096509650336001600160a01b0316876001600160a01b0316146123245760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b038616301461234d5760405163750643af60e01b815260040160405180910390fd5b8a851461236d576040516303fffc4b60e01b815260040160405180910390fd5b604080516001600160a01b0389811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180516001600160e01b031663d505accf60e01b1790529151918e16916123eb91906134ad565b6000604051808303816000865af19150503d8060008114612428576040519150601f19603f3d011682016040523d82523d6000602084013e61242d565b606091505b50505050505050505050610748565b6001600160e01b031981166323f2ebc360e21b1461246d57604051637141605d60e11b815260040160405180910390fd5b6000808080808080806124838a6004818e6137aa565b8101906124909190613858565b97509750975097509750975097509750336001600160a01b0316886001600160a01b0316146124d25760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b03871630146124fb5760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b038a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180516001600160e01b03166323f2ebc360e21b1790529151918f169161258291906134ad565b6000604051808303816000865af19150503d80600081146125bf576040519150601f19603f3d011682016040523d82523d6000602084013e6125c4565b606091505b50505050505050505050505050505050565b6040516001600160a01b0380851660248301528316604482015260648101829052611fe99085906323b872dd60e01b9060840161217f565b80600161261d602060026139bf565b6126279190613544565b60535410612648576040516377ae67b360e11b815260040160405180910390fd5b6000605360008154612659906133f2565b9182905550905060005b60208110156126ea578082901c60011660010361269657826033826020811061268e5761268e6133c6565b015550505050565b603381602081106126a9576126a96133c6565b0154604080516020810192909252810184905260600160405160208183030381529060405280519060200120925080806126e2906133f2565b915050612663565b506121b66139cb565b60018055565b60685460ff1661271c57604051635386698160e01b815260040160405180910390fd5b6068805460ff191690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b390600090a1565b600054610100900460ff166127785760405162461bcd60e51b8152600401611a0f906139e1565b61068c612a8a565b6060604082511061279f57818060200190518101906106d99190613a2c565b81516020036128dc5760005b6020811080156127da57508281815181106127c8576127c86133c6565b01602001516001600160f81b03191615155b156127f157806127e9816133f2565b9150506127ab565b806000036128295750506040805180820190915260128152714e4f545f56414c49445f454e434f44494e4760701b6020820152919050565b60008167ffffffffffffffff81111561284457612844612ed0565b6040519080825280601f01601f19166020018201604052801561286e576020820181803683370190505b50905060005b828110156128d45784818151811061288e5761288e6133c6565b602001015160f81c60f81b8282815181106128ab576128ab6133c6565b60200101906001600160f81b031916908160001a905350806128cc816133f2565b915050612874565b509392505050565b50506040805180820190915260128152714e4f545f56414c49445f454e434f44494e4760701b602082015290565b919050565b606854600090610100900463ffffffff16158015612933575063ffffffff82166001145b15612945575063ffffffff821661296d565b61295a64010000000063ffffffff8416613473565b61296a9063ffffffff851661348a565b90505b600881901c60008181526069602052604081208054600160ff861690811b9182189283905592909190818316900361168057604051630c8d9eab60e31b815260040160405180910390fd5b6000612a0d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612ab19092919063ffffffff16565b8051909150156121b65780806020019051810190612a2b9190613aa3565b6121b65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611a0f565b600054610100900460ff166126f35760405162461bcd60e51b8152600401611a0f906139e1565b6060610969848460008585600080866001600160a01b03168587604051612ad891906134ad565b60006040518083038185875af1925050503d8060008114612b15576040519150601f19603f3d011682016040523d82523d6000602084013e612b1a565b606091505b5091509150612b2b87838387612b36565b979650505050505050565b60608315612ba5578251600003612b9e576001600160a01b0385163b612b9e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611a0f565b5081610969565b6109698383815115612bba5781518083602001fd5b8060405162461bcd60e51b8152600401611a0f9190612d58565b803563ffffffff8116811461290a57600080fd5b6001600160a01b0381168114612bfd57600080fd5b50565b60008060408385031215612c1357600080fd5b612c1c83612bd4565b91506020830135612c2c81612be8565b809150509250929050565b8015158114612bfd57600080fd5b60008083601f840112612c5757600080fd5b50813567ffffffffffffffff811115612c6f57600080fd5b602083019150836020828501011115612c8757600080fd5b9250929050565b600080600080600060808688031215612ca657600080fd5b612caf86612bd4565b94506020860135612cbf81612be8565b93506040860135612ccf81612c37565b9250606086013567ffffffffffffffff811115612ceb57600080fd5b612cf788828901612c45565b969995985093965092949392505050565b60005b83811015612d23578181015183820152602001612d0b565b50506000910152565b60008151808452612d44816020860160208601612d08565b601f01601f19169290920160200192915050565b602081526000612d6b6020830184612d2c565b9392505050565b600060208284031215612d8457600080fd5b8135612d6b81612be8565b60ff81168114612bfd57600080fd5b600080600080600080600060e0888a031215612db957600080fd5b8735612dc481612d8f565b9650612dd260208901612bd4565b95506040880135612de281612be8565b9450612df060608901612bd4565b93506080880135612e0081612be8565b9699959850939692959460a0840135945060c09093013592915050565b600080600060608486031215612e3257600080fd5b612e3b84612bd4565b92506020840135612e4b81612be8565b91506040840135612e5b81612be8565b809150509250925092565b600060208284031215612e7857600080fd5b5035919050565b8061040081018310156106d957600080fd5b60008060006104408486031215612ea757600080fd5b83359250612eb88560208601612e7f565b9150612ec76104208501612bd4565b90509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612f0f57612f0f612ed0565b604052919050565b600067ffffffffffffffff821115612f3157612f31612ed0565b50601f01601f191660200190565b6000612f52612f4d84612f17565b612ee6565b9050828152838383011115612f6657600080fd5b828260208301376000602084830101529392505050565b600082601f830112612f8e57600080fd5b612d6b83833560208501612f3f565b600080600080600060a08688031215612fb557600080fd5b612fbe86612bd4565b94506020860135612fce81612be8565b9350604086013567ffffffffffffffff80821115612feb57600080fd5b612ff789838a01612f7d565b9450606088013591508082111561300d57600080fd5b5061301a88828901612f7d565b925050608086013561302b81612d8f565b809150509295509295909350565b60008060008060008060a0878903121561305257600080fd5b61305b87612bd4565b9550602087013561306b81612be8565b945060408701359350606087013561308281612c37565b9250608087013567ffffffffffffffff81111561309e57600080fd5b6130aa89828a01612c45565b979a9699509497509295939492505050565b600080604083850312156130cf57600080fd5b6130d883612bd4565b91506130e660208401612bd4565b90509250929050565b6000806000806000806000806000806000806109208d8f03121561311257600080fd5b61311c8e8e612e7f565b9b5061312c8e6104008f01612e7f565b9a506108008d013599506108208d013598506108408d013597506131536108608e01612bd4565b96506131636108808e0135612be8565b6108808d013595506131786108a08e01612bd4565b94506131886108c08e0135612be8565b6108c08d013593506108e08d0135925067ffffffffffffffff6109008e013511156131b257600080fd5b6131c38e6109008f01358f01612c45565b81935080925050509295989b509295989b509295989b565b600080600080600080600060c0888a0312156131f657600080fd5b6131ff88612bd4565b9650602088013561320f81612be8565b955060408801359450606088013561322681612be8565b9350608088013561323681612c37565b925060a088013567ffffffffffffffff81111561325257600080fd5b61325e8a828b01612c45565b989b979a50959850939692959293505050565b60008060008060008060c0878903121561328a57600080fd5b61329387612bd4565b955060208701356132a381612be8565b94506132b160408801612bd4565b935060608701356132c181612be8565b925060808701356132d181612be8565b915060a087013567ffffffffffffffff8111156132ed57600080fd5b8701601f810189136132fe57600080fd5b61330d89823560208401612f3f565b9150509295509295509295565b600080600080610460858703121561333157600080fd5b843593506133428660208701612e7f565b92506133516104208601612bd4565b939692955092936104400135925050565b60e09290921b6001600160e01b031916825260601b6001600160601b031916600482015260180190565b600181811c908216806133a057607f821691505b6020821081036133c057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201613404576134046133dc565b5060010190565b60608152600061341e6060830186612d2c565b82810360208401526134308186612d2c565b91505060ff83166040830152949350505050565b60008351613456818460208801612d08565b83519083019061346a818360208801612d08565b01949350505050565b80820281158282048414176106d9576106d96133dc565b808201808211156106d9576106d96133dc565b8183823760009101908152919050565b600082516134bf818460208701612d08565b9190910192915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b63ffffffff861681526001600160a01b03858116602083015284166040820152608060608201819052600090612b2b90830184866134c9565b60006020828403121561353d57600080fd5b5051919050565b818103818111156106d9576106d96133dc565b60ff8916815263ffffffff88811660208301526001600160a01b03888116604084015287821660608401528616608083015260a0820185905261010060c083018190526000916135a984830187612d2c565b925080851660e085015250509998505050505050505050565b6001600160a01b038516815263ffffffff841660208201526060604082018190526000906135f390830184866134c9565b9695505050505050565b601f8211156121b657600081815260208120601f850160051c810160208610156136245750805b601f850160051c820191505b81811015610c4857828155600101613630565b815167ffffffffffffffff81111561365d5761365d612ed0565b6136718161366b845461338c565b846135fd565b602080601f8311600181146136a6576000841561368e5750858301515b600019600386901b1c1916600185901b178555610c48565b600085815260208120601f198616915b828110156136d5578886015182559484019460019091019084016136b6565b50858210156136f35787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60ff8a16815263ffffffff89811660208301526001600160a01b03898116604084015288821660608401528716608083015260a0820186905261010060c0830181905260009161375684830187896134c9565b925080851660e085015250509a9950505050505050505050565b60006020828403121561378257600080fd5b8151612d6b81612d8f565b63ffffffff818116838216019080821115612230576122306133dc565b600080858511156137ba57600080fd5b838611156137c757600080fd5b5050820193919092039150565b6001600160e01b031981358181169160048510156137fc5780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a03121561381f57600080fd5b873561382a81612be8565b9650602088013561383a81612be8565b955060408801359450606088013593506080880135612e0081612d8f565b600080600080600080600080610100898b03121561387557600080fd5b883561388081612be8565b9750602089013561389081612be8565b9650604089013595506060890135945060808901356138ae81612c37565b935060a08901356138be81612d8f565b979a969950949793969295929450505060c08201359160e0013590565b600181815b808511156139165781600019048211156138fc576138fc6133dc565b8085161561390957918102915b93841c93908002906138e0565b509250929050565b60008261392d575060016106d9565b8161393a575060006106d9565b8160018114613950576002811461395a57613976565b60019150506106d9565b60ff84111561396b5761396b6133dc565b50506001821b6106d9565b5060208310610133831016604e8410600b8410161715613999575081810a6106d9565b6139a383836138db565b80600019048211156139b7576139b76133dc565b029392505050565b6000612d6b838361391e565b634e487b7160e01b600052600160045260246000fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600060208284031215613a3e57600080fd5b815167ffffffffffffffff811115613a5557600080fd5b8201601f81018413613a6657600080fd5b8051613a74612f4d82612f17565b818152856020838501011115613a8957600080fd5b613a9a826020830160208601612d08565b95945050505050565b600060208284031215613ab557600080fd5b8151612d6b81612c3756fe6101006040523480156200001257600080fd5b5060405162001b6638038062001b6683398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516116aa620004bc6000396000610237015260008181610307015281816105c001526106a70152600061053a015260008181610379015261050401526116aa6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf1461039b578063dd62ed3e146103ae578063ffa1ad74146103f457600080fd5b8063a457c2d71461034e578063a9059cbb14610361578063cd0d00961461037457600080fd5b806395d89b41116100bd57806395d89b41146102e75780639dc29fac146102ef578063a3c573eb1461030257600080fd5b806370a08231146102915780637ecebe00146102c757600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b610184610430565b60405161019191906113e4565b60405180910390f35b6101ad6101a8366004611479565b6104c2565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad6102043660046114a3565b6104dc565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c1610500565b6101ad610277366004611479565b61055c565b61028f61028a366004611479565b6105a8565b005b6101c161029f3660046114df565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c16102d53660046114df565b60056020526000908152604090205481565b610184610680565b61028f6102fd366004611479565b61068f565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101ad61035c366004611479565b61075e565b6101ad61036f366004611479565b61082f565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f6103a9366004611501565b61083d565b6101c16103bc366004611574565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60606003805461043f906115a7565b80601f016020809104026020016040519081016040528092919081815260200182805461046b906115a7565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b5050505050905090565b6000336104d0818585610b73565b60019150505b92915050565b6000336104ea858285610d27565b6104f5858585610dfe565b506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610537576105324661106d565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d090829086906105a3908790611629565b610b73565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b61067c8282611135565b5050565b60606004805461043f906115a7565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d427269646765000000000000000000000000000000006064820152608401610669565b61067c8282611228565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610669565b6104f58286868403610b73565b6000336104d0818585610dfe565b834211156108cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d6974000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866109268361163c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610991610500565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa158015610a55573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610ad057508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e6174757265000000000000000000000000000000000000000000000000006064820152608401610669565b610b678a8a8a610b73565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610df85781811015610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610669565b610df88484848403610b73565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610df8565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611098610430565b8051602091820120604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000090840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b73ffffffffffffffffffffffffffffffffffffffff82166111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610669565b80600260008282546111c49190611629565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff82166112cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610d1a565b600060208083528351808285015260005b81811015611411578581018301518582016040015282016113f5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461147457600080fd5b919050565b6000806040838503121561148c57600080fd5b61149583611450565b946020939093013593505050565b6000806000606084860312156114b857600080fd5b6114c184611450565b92506114cf60208501611450565b9150604084013590509250925092565b6000602082840312156114f157600080fd5b6114fa82611450565b9392505050565b600080600080600080600060e0888a03121561151c57600080fd5b61152588611450565b965061153360208901611450565b95506040880135945060608801359350608088013560ff8116811461155757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561158757600080fd5b61159083611450565b915061159e60208401611450565b90509250929050565b600181811c908216806115bb57607f821691505b6020821081036115f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104d6576104d66115fa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361166d5761166d6115fa565b506001019056fea26469706673582212208d88fee561cff7120d381c345cfc534cef8229a272dc5809d4bbb685ad67141164736f6c63430008110033a264697066735822122082405b2b21a65efc74f67ed80924b72065405d6bcd7505ac13b3280304fa253264736f6c63430008140033 diff --git a/bindings/ulxly/PolygonZkEVMBridgeV2.go b/bindings/ulxly/PolygonZkEVMBridgeV2.go new file mode 100644 index 00000000..0699052f --- /dev/null +++ b/bindings/ulxly/PolygonZkEVMBridgeV2.go @@ -0,0 +1,1935 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package ulxly + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// UlxlyMetaData contains all meta data concerning the Ulxly contract. +var UlxlyMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"BASE_INIT_BYTECODE_WRAPPED_TOKEN\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"WETHToken\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractTokenWrapped\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"activateEmergencyState\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"bridgeAsset\",\"inputs\":[{\"name\":\"destinationNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"forceUpdateGlobalExitRoot\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"permitData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"bridgeMessage\",\"inputs\":[{\"name\":\"destinationNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"forceUpdateGlobalExitRoot\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"metadata\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"bridgeMessageWETH\",\"inputs\":[{\"name\":\"destinationNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amountWETH\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"forceUpdateGlobalExitRoot\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"metadata\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"calculateRoot\",\"inputs\":[{\"name\":\"leafHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"smtProof\",\"type\":\"bytes32[32]\",\"internalType\":\"bytes32[32]\"},{\"name\":\"index\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"calculateTokenWrapperAddress\",\"inputs\":[{\"name\":\"originNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"originTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimAsset\",\"inputs\":[{\"name\":\"smtProofLocalExitRoot\",\"type\":\"bytes32[32]\",\"internalType\":\"bytes32[32]\"},{\"name\":\"smtProofRollupExitRoot\",\"type\":\"bytes32[32]\",\"internalType\":\"bytes32[32]\"},{\"name\":\"globalIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"mainnetExitRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"rollupExitRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"originNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"originTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"metadata\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"claimMessage\",\"inputs\":[{\"name\":\"smtProofLocalExitRoot\",\"type\":\"bytes32[32]\",\"internalType\":\"bytes32[32]\"},{\"name\":\"smtProofRollupExitRoot\",\"type\":\"bytes32[32]\",\"internalType\":\"bytes32[32]\"},{\"name\":\"globalIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"mainnetExitRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"rollupExitRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"originNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"originAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"metadata\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"claimedBitMap\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deactivateEmergencyState\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"depositCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gasTokenAddress\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gasTokenMetadata\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gasTokenNetwork\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getLeafValue\",\"inputs\":[{\"name\":\"leafType\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"originNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"originAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"metadataHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"getRoot\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTokenMetadata\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getTokenWrappedAddress\",\"inputs\":[{\"name\":\"originNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"originTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalExitRootManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBasePolygonZkEVMGlobalExitRoot\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_networkID\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_gasTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_gasTokenNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_globalExitRootManager\",\"type\":\"address\",\"internalType\":\"contractIBasePolygonZkEVMGlobalExitRoot\"},{\"name\":\"_polygonRollupManager\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_gasTokenMetadata\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isClaimed\",\"inputs\":[{\"name\":\"leafIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"sourceBridgeNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isEmergencyState\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"lastUpdatedDepositCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"networkID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"polygonRollupManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"precalculatedWrapperAddress\",\"inputs\":[{\"name\":\"originNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"originTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"name\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"symbol\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"decimals\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"tokenInfoToWrappedToken\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"updateGlobalExitRoot\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifyMerkleProof\",\"inputs\":[{\"name\":\"leafHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"smtProof\",\"type\":\"bytes32[32]\",\"internalType\":\"bytes32[32]\"},{\"name\":\"index\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"wrappedTokenToTokenInfo\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"originNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"originTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"BridgeEvent\",\"inputs\":[{\"name\":\"leafType\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"},{\"name\":\"originNetwork\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"},{\"name\":\"originAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"destinationNetwork\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"metadata\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"depositCount\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ClaimEvent\",\"inputs\":[{\"name\":\"globalIndex\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"originNetwork\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"},{\"name\":\"originAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"EmergencyStateActivated\",\"inputs\":[],\"anonymous\":false},{\"type\":\"event\",\"name\":\"EmergencyStateDeactivated\",\"inputs\":[],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NewWrappedToken\",\"inputs\":[{\"name\":\"originNetwork\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"},{\"name\":\"originTokenAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"wrappedTokenAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"metadata\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AlreadyClaimed\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AmountDoesNotMatchMsgValue\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"DestinationNetworkInvalid\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"EtherTransferFailed\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedTokenWrappedDeployment\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GasTokenNetworkMustBeZeroOnEther\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GlobalExitRootInvalid\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSmtProof\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MerkleTreeFull\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MessageFailed\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MsgValueNotZero\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NativeTokenIsEther\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoValueInMessagesOnGasTokenNetworks\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotValidAmount\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotValidOwner\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotValidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotValidSpender\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyEmergencyState\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyNotEmergencyState\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyRollupManager\",\"inputs\":[]}]", + Bin: "0x60806040523480156200001157600080fd5b506200001c62000022565b620000e4565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e2576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61565c80620000f46000396000f3fe6080604052600436106101e35760003560e01c806383f2440311610102578063ccaa2d1111610095578063ee25560b11610064578063ee25560b146105cc578063f5efcd79146105f9578063f811bff714610619578063fb5708341461063957600080fd5b8063ccaa2d111461055d578063cd5865791461057d578063d02103ca14610590578063dbc16976146105b757600080fd5b8063bab161bf116100d1578063bab161bf146104d7578063be5831c7146104f9578063c00f14ab1461051d578063cc4616321461053d57600080fd5b806383f24403146104575780638ed7e3f214610477578063aaa13cc214610497578063b8b284d0146104b757600080fd5b80633cbc795b1161017a5780637843298b116101495780637843298b146103d757806379e2cf97146103f757806381b1c1741461040c57806383c43a551461044257600080fd5b80633cbc795b146103495780633e197043146103825780634b2f336d146103a25780635ca1e165146103c257600080fd5b806327aef4e8116101b657806327aef4e8146102795780632dfdf0b51461029b578063318aee3d146102bf5780633c351e101461032957600080fd5b806315064c96146101e85780632072f6c51461021757806322e95f2c1461022e578063240ff37814610266575b600080fd5b3480156101f457600080fd5b506068546102029060ff1681565b60405190151581526020015b60405180910390f35b34801561022357600080fd5b5061022c610659565b005b34801561023a57600080fd5b5061024e610249366004612c00565b61068e565b6040516001600160a01b03909116815260200161020e565b61022c610274366004612c8e565b6106df565b34801561028557600080fd5b5061028e61074f565b60405161020e9190612d58565b3480156102a757600080fd5b506102b160535481565b60405190815260200161020e565b3480156102cb57600080fd5b506103056102da366004612d72565b606b6020526000908152604090205463ffffffff81169064010000000090046001600160a01b031682565b6040805163ffffffff90931683526001600160a01b0390911660208301520161020e565b34801561033557600080fd5b50606d5461024e906001600160a01b031681565b34801561035557600080fd5b50606d5461036d90600160a01b900463ffffffff1681565b60405163ffffffff909116815260200161020e565b34801561038e57600080fd5b506102b161039d366004612d9e565b6107dd565b3480156103ae57600080fd5b50606f5461024e906001600160a01b031681565b3480156103ce57600080fd5b506102b161086a565b3480156103e357600080fd5b5061024e6103f2366004612e1d565b610947565b34801561040357600080fd5b5061022c610971565b34801561041857600080fd5b5061024e610427366004612e66565b606a602052600090815260409020546001600160a01b031681565b34801561044e57600080fd5b5061028e610992565b34801561046357600080fd5b506102b1610472366004612e91565b6109b1565b34801561048357600080fd5b50606c5461024e906001600160a01b031681565b3480156104a357600080fd5b5061024e6104b2366004612f9d565b610a87565b3480156104c357600080fd5b5061022c6104d2366004613039565b610b89565b3480156104e357600080fd5b5060685461036d90610100900463ffffffff1681565b34801561050557600080fd5b5060685461036d90600160c81b900463ffffffff1681565b34801561052957600080fd5b5061028e610538366004612d72565b610c50565b34801561054957600080fd5b506102026105583660046130bc565b610c95565b34801561056957600080fd5b5061022c6105783660046130ef565b610d1f565b61022c61058b3660046131db565b611238565b34801561059c57600080fd5b5060685461024e90600160281b90046001600160a01b031681565b3480156105c357600080fd5b5061022c611689565b3480156105d857600080fd5b506102b16105e7366004612e66565b60696020526000908152604090205481565b34801561060557600080fd5b5061022c6106143660046130ef565b6116bc565b34801561062557600080fd5b5061022c610634366004613271565b611976565b34801561064557600080fd5b5061020261065436600461331a565b611be9565b606c546001600160a01b0316331461068457604051631736745960e31b815260040160405180910390fd5b61068c611c01565b565b6000606a600084846040516020016106a7929190613362565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b031690505b92915050565b60685460ff161561070357604051630bc011ff60e21b815260040160405180910390fd5b341580159061071c5750606f546001600160a01b031615155b1561073a576040516301bd897160e61b815260040160405180910390fd5b610748858534868686611c5d565b5050505050565b606e805461075c9061338c565b80601f01602080910402602001604051908101604052809291908181526020018280546107889061338c565b80156107d55780601f106107aa576101008083540402835291602001916107d5565b820191906000526020600020905b8154815290600101906020018083116107b857829003601f168201915b505050505081565b6040516001600160f81b031960f889901b1660208201526001600160e01b031960e088811b821660218401526001600160601b0319606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b605354600090819081805b602081101561093e578083901c6001166001036108d2576033816020811061089f5761089f6133c6565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506108ff565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b60408051602081018490529081018390526060016040516020818303038152906040528051906020012091508080610936906133f2565b915050610875565b50919392505050565b6000610969848461095785611d27565b61096086611de6565b6104b287611e9e565b949350505050565b605354606854600160c81b900463ffffffff16101561068c5761068c611f56565b60405180611ba00160405280611b668152602001613ac1611b66913981565b600083815b6020811015610a7e57600163ffffffff8516821c81169003610a21578481602081106109e4576109e46133c6565b602002013582604051602001610a04929190918252602082015260400190565b604051602081830303815290604052805190602001209150610a6c565b81858260208110610a3457610a346133c6565b6020020135604051602001610a53929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b80610a76816133f2565b9150506109b6565b50949350505050565b6000808686604051602001610a9d929190613362565b604051602081830303815290604052805190602001209050600060ff60f81b308360405180611ba00160405280611b668152602001613ac1611b669139898989604051602001610aef9392919061340b565b60408051601f1981840301815290829052610b0d9291602001613444565b60405160208183030381529060405280519060200120604051602001610b6594939291906001600160f81b031994909416845260609290921b6001600160601b03191660018401526015830152603582015260550190565b60408051808303601f19018152919052805160209091012098975050505050505050565b60685460ff1615610bad57604051630bc011ff60e21b815260040160405180910390fd5b606f546001600160a01b0316610bd65760405163dde3cda760e01b815260040160405180910390fd5b606f54604051632770a7eb60e21b8152336004820152602481018690526001600160a01b0390911690639dc29fac90604401600060405180830381600087803b158015610c2257600080fd5b505af1158015610c36573d6000803e3d6000fd5b50505050610c48868686868686611c5d565b505050505050565b6060610c5b82611d27565b610c6483611de6565b610c6d84611e9e565b604051602001610c7f9392919061340b565b6040516020818303038152906040529050919050565b6068546000908190610100900463ffffffff16158015610cbb575063ffffffff83166001145b15610ccd575063ffffffff8316610cf5565b610ce264010000000063ffffffff8516613473565b610cf29063ffffffff861661348a565b90505b600881901c600090815260696020526040902054600160ff9092169190911b908116149392505050565b60685460ff1615610d4357604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff8681166101009092041614610d73576040516302caf51760e11b815260040160405180910390fd5b610da78c8c8c8c8c610da260008e8e8e8e8e8e8e604051610d9592919061349d565b60405180910390206107dd565b611fef565b6001600160a01b038616610ee157606f546001600160a01b0316610e765760006001600160a01b03851684825b6040519080825280601f01601f191660200182016040528015610dfe576020820181803683370190505b50604051610e0c91906134ad565b60006040518083038185875af1925050503d8060008114610e49576040519150601f19603f3d011682016040523d82523d6000602084013e610e4e565b606091505b5050905080610e7057604051630ce8f45160e31b815260040160405180910390fd5b506111ce565b606f546040516340c10f1960e01b81526001600160a01b03868116600483015260248201869052909116906340c10f1990604401600060405180830381600087803b158015610ec457600080fd5b505af1158015610ed8573d6000803e3d6000fd5b505050506111ce565b606d546001600160a01b038781169116148015610f0f5750606d5463ffffffff888116600160a01b90920416145b15610f275760006001600160a01b0385168482610dd4565b60685463ffffffff610100909104811690881603610f5857610f536001600160a01b0387168585612153565b6111ce565b60008787604051602001610f6d929190613362565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b031680611168576000610fe58386868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506121bb92505050565b6040516340c10f1960e01b81526001600160a01b03898116600483015260248201899052919250908216906340c10f1990604401600060405180830381600087803b15801561103357600080fd5b505af1158015611047573d6000803e3d6000fd5b5050505080606a600085815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060405180604001604052808b63ffffffff1681526020018a6001600160a01b0316815250606b6000836001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398a8a83888860405161115a9594939291906134f2565b60405180910390a1506111cb565b6040516340c10f1960e01b81526001600160a01b038781166004830152602482018790528216906340c10f1990604401600060405180830381600087803b1580156111b257600080fd5b505af11580156111c6573d6000803e3d6000fd5b505050505b50505b604080518b815263ffffffff891660208201526001600160a01b0388811682840152861660608201526080810185905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a1505050505050505050505050565b60685460ff161561125c57604051630bc011ff60e21b815260040160405180910390fd5b611264612237565b60685463ffffffff610100909104811690881603611295576040516302caf51760e11b815260040160405180910390fd5b6000806060876001600160a01b03881661137b578834146112c95760405163b89240f560e01b815260040160405180910390fd5b606d54606e80546001600160a01b0383169650600160a01b90920463ffffffff169450906112f69061338c565b80601f01602080910402602001604051908101604052809291908181526020018280546113229061338c565b801561136f5780601f106113445761010080835404028352916020019161136f565b820191906000526020600020905b81548152906001019060200180831161135257829003601f168201915b505050505091506115fe565b341561139a5760405163798ee6f160e01b815260040160405180910390fd5b606f546001600160a01b039081169089160361141557604051632770a7eb60e21b8152336004820152602481018a90526001600160a01b03891690639dc29fac90604401600060405180830381600087803b1580156113f857600080fd5b505af115801561140c573d6000803e3d6000fd5b505050506115fe565b6001600160a01b038089166000908152606b602090815260409182902082518084019093525463ffffffff81168352640100000000900490921691810182905290156114ce57604051632770a7eb60e21b8152336004820152602481018b90526001600160a01b038a1690639dc29fac90604401600060405180830381600087803b1580156114a357600080fd5b505af11580156114b7573d6000803e3d6000fd5b5050505080602001519450806000015193506115f1565b85156114e0576114e0898b8989612290565b6040516370a0823160e01b81523060048201526000906001600160a01b038b16906370a0823190602401602060405180830381865afa158015611527573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154b919061352b565b90506115626001600160a01b038b1633308e6125d6565b6040516370a0823160e01b81523060048201526000906001600160a01b038c16906370a0823190602401602060405180830381865afa1580156115a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115cd919061352b565b90506115d98282613544565b6068548c9850610100900463ffffffff169650935050505b6115fa89610c50565b9250505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b600084868e8e868860535460405161163e989796959493929190613557565b60405180910390a1611665611660600085878f8f8789805190602001206107dd565b61260e565b861561167357611673611f56565b5050505061168060018055565b50505050505050565b606c546001600160a01b031633146116b457604051631736745960e31b815260040160405180910390fd5b61068c6126f9565b60685460ff16156116e057604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff8681166101009092041614611710576040516302caf51760e11b815260040160405180910390fd5b6117328c8c8c8c8c610da260018e8e8e8e8e8e8e604051610d9592919061349d565b606f546000906001600160a01b03166117e957846001600160a01b031684888a868660405160240161176794939291906135c2565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b1790525161179c91906134ad565b60006040518083038185875af1925050503d80600081146117d9576040519150601f19603f3d011682016040523d82523d6000602084013e6117de565b606091505b5050809150506118ed565b606f546040516340c10f1960e01b81526001600160a01b03878116600483015260248201879052909116906340c10f1990604401600060405180830381600087803b15801561183757600080fd5b505af115801561184b573d6000803e3d6000fd5b50505050846001600160a01b03168789858560405160240161187094939291906135c2565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b179052516118a591906134ad565b6000604051808303816000865af19150503d80600081146118e2576040519150601f19603f3d011682016040523d82523d6000602084013e6118e7565b606091505b50909150505b8061190b576040516337e391c360e01b815260040160405180910390fd5b604080518c815263ffffffff8a1660208201526001600160a01b0389811682840152871660608201526080810186905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a150505050505050505050505050565b600054610100900460ff16158080156119965750600054600160ff909116105b806119b05750303b1580156119b0575060005460ff166001145b611a185760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015611a3b576000805461ff0019166101001790555b60688054610100600160c81b03191661010063ffffffff8a160265010000000000600160c81b03191617600160281b6001600160a01b038781169190910291909117909155606c80546001600160a01b0319168583161790558616611ac45763ffffffff851615611abf57604051630d43a60960e11b815260040160405180910390fd5b611b93565b606d805463ffffffff8716600160a01b026001600160c01b03199091166001600160a01b03891617179055606e611afb8382613643565b50611b726000801b6012604051602001611b5e91906060808252600d908201526c2bb930b83832b21022ba3432b960991b608082015260a060208201819052600490820152630ae8aa8960e31b60c082015260ff91909116604082015260e00190565b6040516020818303038152906040526121bb565b606f80546001600160a01b0319166001600160a01b03929092169190911790555b611b9b612751565b8015611680576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050565b600081611bf78686866109b1565b1495945050505050565b60685460ff1615611c2557604051630bc011ff60e21b815260040160405180910390fd5b6068805460ff191660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a549790600090a1565b60685463ffffffff610100909104811690871603611c8e576040516302caf51760e11b815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff16338989898888605354604051611ce299989796959493929190613703565b60405180910390a1611d196116606001606860019054906101000a900463ffffffff16338a8a8a8989604051610d9592919061349d565b8215610c4857610c48611f56565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b179052905160609160009182916001600160a01b03861691611d6e91906134ad565b600060405180830381855afa9150503d8060008114611da9576040519150601f19603f3d011682016040523d82523d6000602084013e611dae565b606091505b509150915081611ddd57604051806040016040528060078152602001664e4f5f4e414d4560c81b815250610969565b61096981612780565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b179052905160609160009182916001600160a01b03861691611e2d91906134ad565b600060405180830381855afa9150503d8060008114611e68576040519150601f19603f3d011682016040523d82523d6000602084013e611e6d565b606091505b509150915081611ddd57604051806040016040528060098152602001681393d7d4d6535093d360ba1b815250610969565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b03861691611ee491906134ad565b600060405180830381855afa9150503d8060008114611f1f576040519150601f19603f3d011682016040523d82523d6000602084013e611f24565b606091505b5091509150818015611f37575080516020145b611f42576012610969565b808060200190518101906109699190613770565b6053546068805463ffffffff909216600160c81b0263ffffffff60c81b1990921691909117908190556001600160a01b03600160281b909104166333d6247d611f9d61086a565b6040518263ffffffff1660e01b8152600401611fbb91815260200190565b600060405180830381600087803b158015611fd557600080fd5b505af1158015611fe9573d6000803e3d6000fd5b50505050565b606854604080516020808201879052818301869052825180830384018152606083019384905280519101206312bd9b1960e11b9092526064810191909152600091600160281b90046001600160a01b03169063257b3632906084016020604051808303816000875af1158015612069573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208d919061352b565b9050806000036120af57604051622f6fad60e01b815260040160405180910390fd5b600080680100000000000000008716156120f4578691506120d2848a8489611be9565b6120ef576040516338105f3b60e21b815260040160405180910390fd5b61213e565b602087901c61210481600161378d565b915087925061211f612117868c866109b1565b8a8389611be9565b61213c576040516338105f3b60e21b815260040160405180910390fd5b505b612148828261290f565b505050505050505050565b6040516001600160a01b0383166024820152604481018290526121b690849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526129b8565b505050565b60008060405180611ba00160405280611b668152602001613ac1611b669139836040516020016121ec929190613444565b6040516020818303038152906040529050838151602083016000f591506001600160a01b038216612230576040516305f7d84960e51b815260040160405180910390fd5b5092915050565b6002600154036122895760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611a0f565b6002600155565b600061229f60048284866137aa565b6122a8916137d4565b9050632afa533160e01b6001600160e01b031982160161243c5760008080808080806122d7896004818d6137aa565b8101906122e49190613804565b9650965096509650965096509650336001600160a01b0316876001600160a01b0316146123245760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b038616301461234d5760405163750643af60e01b815260040160405180910390fd5b8a851461236d576040516303fffc4b60e01b815260040160405180910390fd5b604080516001600160a01b0389811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180516001600160e01b031663d505accf60e01b1790529151918e16916123eb91906134ad565b6000604051808303816000865af19150503d8060008114612428576040519150601f19603f3d011682016040523d82523d6000602084013e61242d565b606091505b50505050505050505050610748565b6001600160e01b031981166323f2ebc360e21b1461246d57604051637141605d60e11b815260040160405180910390fd5b6000808080808080806124838a6004818e6137aa565b8101906124909190613858565b97509750975097509750975097509750336001600160a01b0316886001600160a01b0316146124d25760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b03871630146124fb5760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b038a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180516001600160e01b03166323f2ebc360e21b1790529151918f169161258291906134ad565b6000604051808303816000865af19150503d80600081146125bf576040519150601f19603f3d011682016040523d82523d6000602084013e6125c4565b606091505b50505050505050505050505050505050565b6040516001600160a01b0380851660248301528316604482015260648101829052611fe99085906323b872dd60e01b9060840161217f565b80600161261d602060026139bf565b6126279190613544565b60535410612648576040516377ae67b360e11b815260040160405180910390fd5b6000605360008154612659906133f2565b9182905550905060005b60208110156126ea578082901c60011660010361269657826033826020811061268e5761268e6133c6565b015550505050565b603381602081106126a9576126a96133c6565b0154604080516020810192909252810184905260600160405160208183030381529060405280519060200120925080806126e2906133f2565b915050612663565b506121b66139cb565b60018055565b60685460ff1661271c57604051635386698160e01b815260040160405180910390fd5b6068805460ff191690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b390600090a1565b600054610100900460ff166127785760405162461bcd60e51b8152600401611a0f906139e1565b61068c612a8a565b6060604082511061279f57818060200190518101906106d99190613a2c565b81516020036128dc5760005b6020811080156127da57508281815181106127c8576127c86133c6565b01602001516001600160f81b03191615155b156127f157806127e9816133f2565b9150506127ab565b806000036128295750506040805180820190915260128152714e4f545f56414c49445f454e434f44494e4760701b6020820152919050565b60008167ffffffffffffffff81111561284457612844612ed0565b6040519080825280601f01601f19166020018201604052801561286e576020820181803683370190505b50905060005b828110156128d45784818151811061288e5761288e6133c6565b602001015160f81c60f81b8282815181106128ab576128ab6133c6565b60200101906001600160f81b031916908160001a905350806128cc816133f2565b915050612874565b509392505050565b50506040805180820190915260128152714e4f545f56414c49445f454e434f44494e4760701b602082015290565b919050565b606854600090610100900463ffffffff16158015612933575063ffffffff82166001145b15612945575063ffffffff821661296d565b61295a64010000000063ffffffff8416613473565b61296a9063ffffffff851661348a565b90505b600881901c60008181526069602052604081208054600160ff861690811b9182189283905592909190818316900361168057604051630c8d9eab60e31b815260040160405180910390fd5b6000612a0d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612ab19092919063ffffffff16565b8051909150156121b65780806020019051810190612a2b9190613aa3565b6121b65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611a0f565b600054610100900460ff166126f35760405162461bcd60e51b8152600401611a0f906139e1565b6060610969848460008585600080866001600160a01b03168587604051612ad891906134ad565b60006040518083038185875af1925050503d8060008114612b15576040519150601f19603f3d011682016040523d82523d6000602084013e612b1a565b606091505b5091509150612b2b87838387612b36565b979650505050505050565b60608315612ba5578251600003612b9e576001600160a01b0385163b612b9e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611a0f565b5081610969565b6109698383815115612bba5781518083602001fd5b8060405162461bcd60e51b8152600401611a0f9190612d58565b803563ffffffff8116811461290a57600080fd5b6001600160a01b0381168114612bfd57600080fd5b50565b60008060408385031215612c1357600080fd5b612c1c83612bd4565b91506020830135612c2c81612be8565b809150509250929050565b8015158114612bfd57600080fd5b60008083601f840112612c5757600080fd5b50813567ffffffffffffffff811115612c6f57600080fd5b602083019150836020828501011115612c8757600080fd5b9250929050565b600080600080600060808688031215612ca657600080fd5b612caf86612bd4565b94506020860135612cbf81612be8565b93506040860135612ccf81612c37565b9250606086013567ffffffffffffffff811115612ceb57600080fd5b612cf788828901612c45565b969995985093965092949392505050565b60005b83811015612d23578181015183820152602001612d0b565b50506000910152565b60008151808452612d44816020860160208601612d08565b601f01601f19169290920160200192915050565b602081526000612d6b6020830184612d2c565b9392505050565b600060208284031215612d8457600080fd5b8135612d6b81612be8565b60ff81168114612bfd57600080fd5b600080600080600080600060e0888a031215612db957600080fd5b8735612dc481612d8f565b9650612dd260208901612bd4565b95506040880135612de281612be8565b9450612df060608901612bd4565b93506080880135612e0081612be8565b9699959850939692959460a0840135945060c09093013592915050565b600080600060608486031215612e3257600080fd5b612e3b84612bd4565b92506020840135612e4b81612be8565b91506040840135612e5b81612be8565b809150509250925092565b600060208284031215612e7857600080fd5b5035919050565b8061040081018310156106d957600080fd5b60008060006104408486031215612ea757600080fd5b83359250612eb88560208601612e7f565b9150612ec76104208501612bd4565b90509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612f0f57612f0f612ed0565b604052919050565b600067ffffffffffffffff821115612f3157612f31612ed0565b50601f01601f191660200190565b6000612f52612f4d84612f17565b612ee6565b9050828152838383011115612f6657600080fd5b828260208301376000602084830101529392505050565b600082601f830112612f8e57600080fd5b612d6b83833560208501612f3f565b600080600080600060a08688031215612fb557600080fd5b612fbe86612bd4565b94506020860135612fce81612be8565b9350604086013567ffffffffffffffff80821115612feb57600080fd5b612ff789838a01612f7d565b9450606088013591508082111561300d57600080fd5b5061301a88828901612f7d565b925050608086013561302b81612d8f565b809150509295509295909350565b60008060008060008060a0878903121561305257600080fd5b61305b87612bd4565b9550602087013561306b81612be8565b945060408701359350606087013561308281612c37565b9250608087013567ffffffffffffffff81111561309e57600080fd5b6130aa89828a01612c45565b979a9699509497509295939492505050565b600080604083850312156130cf57600080fd5b6130d883612bd4565b91506130e660208401612bd4565b90509250929050565b6000806000806000806000806000806000806109208d8f03121561311257600080fd5b61311c8e8e612e7f565b9b5061312c8e6104008f01612e7f565b9a506108008d013599506108208d013598506108408d013597506131536108608e01612bd4565b96506131636108808e0135612be8565b6108808d013595506131786108a08e01612bd4565b94506131886108c08e0135612be8565b6108c08d013593506108e08d0135925067ffffffffffffffff6109008e013511156131b257600080fd5b6131c38e6109008f01358f01612c45565b81935080925050509295989b509295989b509295989b565b600080600080600080600060c0888a0312156131f657600080fd5b6131ff88612bd4565b9650602088013561320f81612be8565b955060408801359450606088013561322681612be8565b9350608088013561323681612c37565b925060a088013567ffffffffffffffff81111561325257600080fd5b61325e8a828b01612c45565b989b979a50959850939692959293505050565b60008060008060008060c0878903121561328a57600080fd5b61329387612bd4565b955060208701356132a381612be8565b94506132b160408801612bd4565b935060608701356132c181612be8565b925060808701356132d181612be8565b915060a087013567ffffffffffffffff8111156132ed57600080fd5b8701601f810189136132fe57600080fd5b61330d89823560208401612f3f565b9150509295509295509295565b600080600080610460858703121561333157600080fd5b843593506133428660208701612e7f565b92506133516104208601612bd4565b939692955092936104400135925050565b60e09290921b6001600160e01b031916825260601b6001600160601b031916600482015260180190565b600181811c908216806133a057607f821691505b6020821081036133c057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201613404576134046133dc565b5060010190565b60608152600061341e6060830186612d2c565b82810360208401526134308186612d2c565b91505060ff83166040830152949350505050565b60008351613456818460208801612d08565b83519083019061346a818360208801612d08565b01949350505050565b80820281158282048414176106d9576106d96133dc565b808201808211156106d9576106d96133dc565b8183823760009101908152919050565b600082516134bf818460208701612d08565b9190910192915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b63ffffffff861681526001600160a01b03858116602083015284166040820152608060608201819052600090612b2b90830184866134c9565b60006020828403121561353d57600080fd5b5051919050565b818103818111156106d9576106d96133dc565b60ff8916815263ffffffff88811660208301526001600160a01b03888116604084015287821660608401528616608083015260a0820185905261010060c083018190526000916135a984830187612d2c565b925080851660e085015250509998505050505050505050565b6001600160a01b038516815263ffffffff841660208201526060604082018190526000906135f390830184866134c9565b9695505050505050565b601f8211156121b657600081815260208120601f850160051c810160208610156136245750805b601f850160051c820191505b81811015610c4857828155600101613630565b815167ffffffffffffffff81111561365d5761365d612ed0565b6136718161366b845461338c565b846135fd565b602080601f8311600181146136a6576000841561368e5750858301515b600019600386901b1c1916600185901b178555610c48565b600085815260208120601f198616915b828110156136d5578886015182559484019460019091019084016136b6565b50858210156136f35787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60ff8a16815263ffffffff89811660208301526001600160a01b03898116604084015288821660608401528716608083015260a0820186905261010060c0830181905260009161375684830187896134c9565b925080851660e085015250509a9950505050505050505050565b60006020828403121561378257600080fd5b8151612d6b81612d8f565b63ffffffff818116838216019080821115612230576122306133dc565b600080858511156137ba57600080fd5b838611156137c757600080fd5b5050820193919092039150565b6001600160e01b031981358181169160048510156137fc5780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a03121561381f57600080fd5b873561382a81612be8565b9650602088013561383a81612be8565b955060408801359450606088013593506080880135612e0081612d8f565b600080600080600080600080610100898b03121561387557600080fd5b883561388081612be8565b9750602089013561389081612be8565b9650604089013595506060890135945060808901356138ae81612c37565b935060a08901356138be81612d8f565b979a969950949793969295929450505060c08201359160e0013590565b600181815b808511156139165781600019048211156138fc576138fc6133dc565b8085161561390957918102915b93841c93908002906138e0565b509250929050565b60008261392d575060016106d9565b8161393a575060006106d9565b8160018114613950576002811461395a57613976565b60019150506106d9565b60ff84111561396b5761396b6133dc565b50506001821b6106d9565b5060208310610133831016604e8410600b8410161715613999575081810a6106d9565b6139a383836138db565b80600019048211156139b7576139b76133dc565b029392505050565b6000612d6b838361391e565b634e487b7160e01b600052600160045260246000fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b600060208284031215613a3e57600080fd5b815167ffffffffffffffff811115613a5557600080fd5b8201601f81018413613a6657600080fd5b8051613a74612f4d82612f17565b818152856020838501011115613a8957600080fd5b613a9a826020830160208601612d08565b95945050505050565b600060208284031215613ab557600080fd5b8151612d6b81612c3756fe6101006040523480156200001257600080fd5b5060405162001b6638038062001b6683398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516116aa620004bc6000396000610237015260008181610307015281816105c001526106a70152600061053a015260008181610379015261050401526116aa6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf1461039b578063dd62ed3e146103ae578063ffa1ad74146103f457600080fd5b8063a457c2d71461034e578063a9059cbb14610361578063cd0d00961461037457600080fd5b806395d89b41116100bd57806395d89b41146102e75780639dc29fac146102ef578063a3c573eb1461030257600080fd5b806370a08231146102915780637ecebe00146102c757600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b610184610430565b60405161019191906113e4565b60405180910390f35b6101ad6101a8366004611479565b6104c2565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad6102043660046114a3565b6104dc565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c1610500565b6101ad610277366004611479565b61055c565b61028f61028a366004611479565b6105a8565b005b6101c161029f3660046114df565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c16102d53660046114df565b60056020526000908152604090205481565b610184610680565b61028f6102fd366004611479565b61068f565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101ad61035c366004611479565b61075e565b6101ad61036f366004611479565b61082f565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f6103a9366004611501565b61083d565b6101c16103bc366004611574565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60606003805461043f906115a7565b80601f016020809104026020016040519081016040528092919081815260200182805461046b906115a7565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b5050505050905090565b6000336104d0818585610b73565b60019150505b92915050565b6000336104ea858285610d27565b6104f5858585610dfe565b506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610537576105324661106d565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d090829086906105a3908790611629565b610b73565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b61067c8282611135565b5050565b60606004805461043f906115a7565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d427269646765000000000000000000000000000000006064820152608401610669565b61067c8282611228565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610669565b6104f58286868403610b73565b6000336104d0818585610dfe565b834211156108cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d6974000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866109268361163c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610991610500565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa158015610a55573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610ad057508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e6174757265000000000000000000000000000000000000000000000000006064820152608401610669565b610b678a8a8a610b73565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610df85781811015610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610669565b610df88484848403610b73565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610df8565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611098610430565b8051602091820120604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000090840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b73ffffffffffffffffffffffffffffffffffffffff82166111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610669565b80600260008282546111c49190611629565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff82166112cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610d1a565b600060208083528351808285015260005b81811015611411578581018301518582016040015282016113f5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461147457600080fd5b919050565b6000806040838503121561148c57600080fd5b61149583611450565b946020939093013593505050565b6000806000606084860312156114b857600080fd5b6114c184611450565b92506114cf60208501611450565b9150604084013590509250925092565b6000602082840312156114f157600080fd5b6114fa82611450565b9392505050565b600080600080600080600060e0888a03121561151c57600080fd5b61152588611450565b965061153360208901611450565b95506040880135945060608801359350608088013560ff8116811461155757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561158757600080fd5b61159083611450565b915061159e60208401611450565b90509250929050565b600181811c908216806115bb57607f821691505b6020821081036115f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104d6576104d66115fa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361166d5761166d6115fa565b506001019056fea26469706673582212208d88fee561cff7120d381c345cfc534cef8229a272dc5809d4bbb685ad67141164736f6c63430008110033a264697066735822122082405b2b21a65efc74f67ed80924b72065405d6bcd7505ac13b3280304fa253264736f6c63430008140033", +} + +// UlxlyABI is the input ABI used to generate the binding from. +// Deprecated: Use UlxlyMetaData.ABI instead. +var UlxlyABI = UlxlyMetaData.ABI + +// UlxlyBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use UlxlyMetaData.Bin instead. +var UlxlyBin = UlxlyMetaData.Bin + +// DeployUlxly deploys a new Ethereum contract, binding an instance of Ulxly to it. +func DeployUlxly(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Ulxly, error) { + parsed, err := UlxlyMetaData.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(UlxlyBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Ulxly{UlxlyCaller: UlxlyCaller{contract: contract}, UlxlyTransactor: UlxlyTransactor{contract: contract}, UlxlyFilterer: UlxlyFilterer{contract: contract}}, nil +} + +// Ulxly is an auto generated Go binding around an Ethereum contract. +type Ulxly struct { + UlxlyCaller // Read-only binding to the contract + UlxlyTransactor // Write-only binding to the contract + UlxlyFilterer // Log filterer for contract events +} + +// UlxlyCaller is an auto generated read-only Go binding around an Ethereum contract. +type UlxlyCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UlxlyTransactor is an auto generated write-only Go binding around an Ethereum contract. +type UlxlyTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UlxlyFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type UlxlyFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UlxlySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type UlxlySession struct { + Contract *Ulxly // 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 +} + +// UlxlyCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type UlxlyCallerSession struct { + Contract *UlxlyCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// UlxlyTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type UlxlyTransactorSession struct { + Contract *UlxlyTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// UlxlyRaw is an auto generated low-level Go binding around an Ethereum contract. +type UlxlyRaw struct { + Contract *Ulxly // Generic contract binding to access the raw methods on +} + +// UlxlyCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type UlxlyCallerRaw struct { + Contract *UlxlyCaller // Generic read-only contract binding to access the raw methods on +} + +// UlxlyTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type UlxlyTransactorRaw struct { + Contract *UlxlyTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewUlxly creates a new instance of Ulxly, bound to a specific deployed contract. +func NewUlxly(address common.Address, backend bind.ContractBackend) (*Ulxly, error) { + contract, err := bindUlxly(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Ulxly{UlxlyCaller: UlxlyCaller{contract: contract}, UlxlyTransactor: UlxlyTransactor{contract: contract}, UlxlyFilterer: UlxlyFilterer{contract: contract}}, nil +} + +// NewUlxlyCaller creates a new read-only instance of Ulxly, bound to a specific deployed contract. +func NewUlxlyCaller(address common.Address, caller bind.ContractCaller) (*UlxlyCaller, error) { + contract, err := bindUlxly(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &UlxlyCaller{contract: contract}, nil +} + +// NewUlxlyTransactor creates a new write-only instance of Ulxly, bound to a specific deployed contract. +func NewUlxlyTransactor(address common.Address, transactor bind.ContractTransactor) (*UlxlyTransactor, error) { + contract, err := bindUlxly(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &UlxlyTransactor{contract: contract}, nil +} + +// NewUlxlyFilterer creates a new log filterer instance of Ulxly, bound to a specific deployed contract. +func NewUlxlyFilterer(address common.Address, filterer bind.ContractFilterer) (*UlxlyFilterer, error) { + contract, err := bindUlxly(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &UlxlyFilterer{contract: contract}, nil +} + +// bindUlxly binds a generic wrapper to an already deployed contract. +func bindUlxly(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := UlxlyMetaData.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 (_Ulxly *UlxlyRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Ulxly.Contract.UlxlyCaller.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 (_Ulxly *UlxlyRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Ulxly.Contract.UlxlyTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Ulxly *UlxlyRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Ulxly.Contract.UlxlyTransactor.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 (_Ulxly *UlxlyCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Ulxly.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 (_Ulxly *UlxlyTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Ulxly.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Ulxly *UlxlyTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Ulxly.Contract.contract.Transact(opts, method, params...) +} + +// BASEINITBYTECODEWRAPPEDTOKEN is a free data retrieval call binding the contract method 0x83c43a55. +// +// Solidity: function BASE_INIT_BYTECODE_WRAPPED_TOKEN() view returns(bytes) +func (_Ulxly *UlxlyCaller) BASEINITBYTECODEWRAPPEDTOKEN(opts *bind.CallOpts) ([]byte, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "BASE_INIT_BYTECODE_WRAPPED_TOKEN") + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// BASEINITBYTECODEWRAPPEDTOKEN is a free data retrieval call binding the contract method 0x83c43a55. +// +// Solidity: function BASE_INIT_BYTECODE_WRAPPED_TOKEN() view returns(bytes) +func (_Ulxly *UlxlySession) BASEINITBYTECODEWRAPPEDTOKEN() ([]byte, error) { + return _Ulxly.Contract.BASEINITBYTECODEWRAPPEDTOKEN(&_Ulxly.CallOpts) +} + +// BASEINITBYTECODEWRAPPEDTOKEN is a free data retrieval call binding the contract method 0x83c43a55. +// +// Solidity: function BASE_INIT_BYTECODE_WRAPPED_TOKEN() view returns(bytes) +func (_Ulxly *UlxlyCallerSession) BASEINITBYTECODEWRAPPEDTOKEN() ([]byte, error) { + return _Ulxly.Contract.BASEINITBYTECODEWRAPPEDTOKEN(&_Ulxly.CallOpts) +} + +// WETHToken is a free data retrieval call binding the contract method 0x4b2f336d. +// +// Solidity: function WETHToken() view returns(address) +func (_Ulxly *UlxlyCaller) WETHToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "WETHToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// WETHToken is a free data retrieval call binding the contract method 0x4b2f336d. +// +// Solidity: function WETHToken() view returns(address) +func (_Ulxly *UlxlySession) WETHToken() (common.Address, error) { + return _Ulxly.Contract.WETHToken(&_Ulxly.CallOpts) +} + +// WETHToken is a free data retrieval call binding the contract method 0x4b2f336d. +// +// Solidity: function WETHToken() view returns(address) +func (_Ulxly *UlxlyCallerSession) WETHToken() (common.Address, error) { + return _Ulxly.Contract.WETHToken(&_Ulxly.CallOpts) +} + +// CalculateRoot is a free data retrieval call binding the contract method 0x83f24403. +// +// Solidity: function calculateRoot(bytes32 leafHash, bytes32[32] smtProof, uint32 index) pure returns(bytes32) +func (_Ulxly *UlxlyCaller) CalculateRoot(opts *bind.CallOpts, leafHash [32]byte, smtProof [32][32]byte, index uint32) ([32]byte, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "calculateRoot", leafHash, smtProof, index) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// CalculateRoot is a free data retrieval call binding the contract method 0x83f24403. +// +// Solidity: function calculateRoot(bytes32 leafHash, bytes32[32] smtProof, uint32 index) pure returns(bytes32) +func (_Ulxly *UlxlySession) CalculateRoot(leafHash [32]byte, smtProof [32][32]byte, index uint32) ([32]byte, error) { + return _Ulxly.Contract.CalculateRoot(&_Ulxly.CallOpts, leafHash, smtProof, index) +} + +// CalculateRoot is a free data retrieval call binding the contract method 0x83f24403. +// +// Solidity: function calculateRoot(bytes32 leafHash, bytes32[32] smtProof, uint32 index) pure returns(bytes32) +func (_Ulxly *UlxlyCallerSession) CalculateRoot(leafHash [32]byte, smtProof [32][32]byte, index uint32) ([32]byte, error) { + return _Ulxly.Contract.CalculateRoot(&_Ulxly.CallOpts, leafHash, smtProof, index) +} + +// CalculateTokenWrapperAddress is a free data retrieval call binding the contract method 0x7843298b. +// +// Solidity: function calculateTokenWrapperAddress(uint32 originNetwork, address originTokenAddress, address token) view returns(address) +func (_Ulxly *UlxlyCaller) CalculateTokenWrapperAddress(opts *bind.CallOpts, originNetwork uint32, originTokenAddress common.Address, token common.Address) (common.Address, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "calculateTokenWrapperAddress", originNetwork, originTokenAddress, token) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// CalculateTokenWrapperAddress is a free data retrieval call binding the contract method 0x7843298b. +// +// Solidity: function calculateTokenWrapperAddress(uint32 originNetwork, address originTokenAddress, address token) view returns(address) +func (_Ulxly *UlxlySession) CalculateTokenWrapperAddress(originNetwork uint32, originTokenAddress common.Address, token common.Address) (common.Address, error) { + return _Ulxly.Contract.CalculateTokenWrapperAddress(&_Ulxly.CallOpts, originNetwork, originTokenAddress, token) +} + +// CalculateTokenWrapperAddress is a free data retrieval call binding the contract method 0x7843298b. +// +// Solidity: function calculateTokenWrapperAddress(uint32 originNetwork, address originTokenAddress, address token) view returns(address) +func (_Ulxly *UlxlyCallerSession) CalculateTokenWrapperAddress(originNetwork uint32, originTokenAddress common.Address, token common.Address) (common.Address, error) { + return _Ulxly.Contract.CalculateTokenWrapperAddress(&_Ulxly.CallOpts, originNetwork, originTokenAddress, token) +} + +// ClaimedBitMap is a free data retrieval call binding the contract method 0xee25560b. +// +// Solidity: function claimedBitMap(uint256 ) view returns(uint256) +func (_Ulxly *UlxlyCaller) ClaimedBitMap(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "claimedBitMap", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ClaimedBitMap is a free data retrieval call binding the contract method 0xee25560b. +// +// Solidity: function claimedBitMap(uint256 ) view returns(uint256) +func (_Ulxly *UlxlySession) ClaimedBitMap(arg0 *big.Int) (*big.Int, error) { + return _Ulxly.Contract.ClaimedBitMap(&_Ulxly.CallOpts, arg0) +} + +// ClaimedBitMap is a free data retrieval call binding the contract method 0xee25560b. +// +// Solidity: function claimedBitMap(uint256 ) view returns(uint256) +func (_Ulxly *UlxlyCallerSession) ClaimedBitMap(arg0 *big.Int) (*big.Int, error) { + return _Ulxly.Contract.ClaimedBitMap(&_Ulxly.CallOpts, arg0) +} + +// DepositCount is a free data retrieval call binding the contract method 0x2dfdf0b5. +// +// Solidity: function depositCount() view returns(uint256) +func (_Ulxly *UlxlyCaller) DepositCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "depositCount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// DepositCount is a free data retrieval call binding the contract method 0x2dfdf0b5. +// +// Solidity: function depositCount() view returns(uint256) +func (_Ulxly *UlxlySession) DepositCount() (*big.Int, error) { + return _Ulxly.Contract.DepositCount(&_Ulxly.CallOpts) +} + +// DepositCount is a free data retrieval call binding the contract method 0x2dfdf0b5. +// +// Solidity: function depositCount() view returns(uint256) +func (_Ulxly *UlxlyCallerSession) DepositCount() (*big.Int, error) { + return _Ulxly.Contract.DepositCount(&_Ulxly.CallOpts) +} + +// GasTokenAddress is a free data retrieval call binding the contract method 0x3c351e10. +// +// Solidity: function gasTokenAddress() view returns(address) +func (_Ulxly *UlxlyCaller) GasTokenAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "gasTokenAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GasTokenAddress is a free data retrieval call binding the contract method 0x3c351e10. +// +// Solidity: function gasTokenAddress() view returns(address) +func (_Ulxly *UlxlySession) GasTokenAddress() (common.Address, error) { + return _Ulxly.Contract.GasTokenAddress(&_Ulxly.CallOpts) +} + +// GasTokenAddress is a free data retrieval call binding the contract method 0x3c351e10. +// +// Solidity: function gasTokenAddress() view returns(address) +func (_Ulxly *UlxlyCallerSession) GasTokenAddress() (common.Address, error) { + return _Ulxly.Contract.GasTokenAddress(&_Ulxly.CallOpts) +} + +// GasTokenMetadata is a free data retrieval call binding the contract method 0x27aef4e8. +// +// Solidity: function gasTokenMetadata() view returns(bytes) +func (_Ulxly *UlxlyCaller) GasTokenMetadata(opts *bind.CallOpts) ([]byte, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "gasTokenMetadata") + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// GasTokenMetadata is a free data retrieval call binding the contract method 0x27aef4e8. +// +// Solidity: function gasTokenMetadata() view returns(bytes) +func (_Ulxly *UlxlySession) GasTokenMetadata() ([]byte, error) { + return _Ulxly.Contract.GasTokenMetadata(&_Ulxly.CallOpts) +} + +// GasTokenMetadata is a free data retrieval call binding the contract method 0x27aef4e8. +// +// Solidity: function gasTokenMetadata() view returns(bytes) +func (_Ulxly *UlxlyCallerSession) GasTokenMetadata() ([]byte, error) { + return _Ulxly.Contract.GasTokenMetadata(&_Ulxly.CallOpts) +} + +// GasTokenNetwork is a free data retrieval call binding the contract method 0x3cbc795b. +// +// Solidity: function gasTokenNetwork() view returns(uint32) +func (_Ulxly *UlxlyCaller) GasTokenNetwork(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "gasTokenNetwork") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// GasTokenNetwork is a free data retrieval call binding the contract method 0x3cbc795b. +// +// Solidity: function gasTokenNetwork() view returns(uint32) +func (_Ulxly *UlxlySession) GasTokenNetwork() (uint32, error) { + return _Ulxly.Contract.GasTokenNetwork(&_Ulxly.CallOpts) +} + +// GasTokenNetwork is a free data retrieval call binding the contract method 0x3cbc795b. +// +// Solidity: function gasTokenNetwork() view returns(uint32) +func (_Ulxly *UlxlyCallerSession) GasTokenNetwork() (uint32, error) { + return _Ulxly.Contract.GasTokenNetwork(&_Ulxly.CallOpts) +} + +// GetLeafValue is a free data retrieval call binding the contract method 0x3e197043. +// +// Solidity: function getLeafValue(uint8 leafType, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes32 metadataHash) pure returns(bytes32) +func (_Ulxly *UlxlyCaller) GetLeafValue(opts *bind.CallOpts, leafType uint8, originNetwork uint32, originAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadataHash [32]byte) ([32]byte, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "getLeafValue", leafType, originNetwork, originAddress, destinationNetwork, destinationAddress, amount, metadataHash) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetLeafValue is a free data retrieval call binding the contract method 0x3e197043. +// +// Solidity: function getLeafValue(uint8 leafType, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes32 metadataHash) pure returns(bytes32) +func (_Ulxly *UlxlySession) GetLeafValue(leafType uint8, originNetwork uint32, originAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadataHash [32]byte) ([32]byte, error) { + return _Ulxly.Contract.GetLeafValue(&_Ulxly.CallOpts, leafType, originNetwork, originAddress, destinationNetwork, destinationAddress, amount, metadataHash) +} + +// GetLeafValue is a free data retrieval call binding the contract method 0x3e197043. +// +// Solidity: function getLeafValue(uint8 leafType, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes32 metadataHash) pure returns(bytes32) +func (_Ulxly *UlxlyCallerSession) GetLeafValue(leafType uint8, originNetwork uint32, originAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadataHash [32]byte) ([32]byte, error) { + return _Ulxly.Contract.GetLeafValue(&_Ulxly.CallOpts, leafType, originNetwork, originAddress, destinationNetwork, destinationAddress, amount, metadataHash) +} + +// GetRoot is a free data retrieval call binding the contract method 0x5ca1e165. +// +// Solidity: function getRoot() view returns(bytes32) +func (_Ulxly *UlxlyCaller) GetRoot(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "getRoot") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetRoot is a free data retrieval call binding the contract method 0x5ca1e165. +// +// Solidity: function getRoot() view returns(bytes32) +func (_Ulxly *UlxlySession) GetRoot() ([32]byte, error) { + return _Ulxly.Contract.GetRoot(&_Ulxly.CallOpts) +} + +// GetRoot is a free data retrieval call binding the contract method 0x5ca1e165. +// +// Solidity: function getRoot() view returns(bytes32) +func (_Ulxly *UlxlyCallerSession) GetRoot() ([32]byte, error) { + return _Ulxly.Contract.GetRoot(&_Ulxly.CallOpts) +} + +// GetTokenMetadata is a free data retrieval call binding the contract method 0xc00f14ab. +// +// Solidity: function getTokenMetadata(address token) view returns(bytes) +func (_Ulxly *UlxlyCaller) GetTokenMetadata(opts *bind.CallOpts, token common.Address) ([]byte, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "getTokenMetadata", token) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// GetTokenMetadata is a free data retrieval call binding the contract method 0xc00f14ab. +// +// Solidity: function getTokenMetadata(address token) view returns(bytes) +func (_Ulxly *UlxlySession) GetTokenMetadata(token common.Address) ([]byte, error) { + return _Ulxly.Contract.GetTokenMetadata(&_Ulxly.CallOpts, token) +} + +// GetTokenMetadata is a free data retrieval call binding the contract method 0xc00f14ab. +// +// Solidity: function getTokenMetadata(address token) view returns(bytes) +func (_Ulxly *UlxlyCallerSession) GetTokenMetadata(token common.Address) ([]byte, error) { + return _Ulxly.Contract.GetTokenMetadata(&_Ulxly.CallOpts, token) +} + +// GetTokenWrappedAddress is a free data retrieval call binding the contract method 0x22e95f2c. +// +// Solidity: function getTokenWrappedAddress(uint32 originNetwork, address originTokenAddress) view returns(address) +func (_Ulxly *UlxlyCaller) GetTokenWrappedAddress(opts *bind.CallOpts, originNetwork uint32, originTokenAddress common.Address) (common.Address, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "getTokenWrappedAddress", originNetwork, originTokenAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetTokenWrappedAddress is a free data retrieval call binding the contract method 0x22e95f2c. +// +// Solidity: function getTokenWrappedAddress(uint32 originNetwork, address originTokenAddress) view returns(address) +func (_Ulxly *UlxlySession) GetTokenWrappedAddress(originNetwork uint32, originTokenAddress common.Address) (common.Address, error) { + return _Ulxly.Contract.GetTokenWrappedAddress(&_Ulxly.CallOpts, originNetwork, originTokenAddress) +} + +// GetTokenWrappedAddress is a free data retrieval call binding the contract method 0x22e95f2c. +// +// Solidity: function getTokenWrappedAddress(uint32 originNetwork, address originTokenAddress) view returns(address) +func (_Ulxly *UlxlyCallerSession) GetTokenWrappedAddress(originNetwork uint32, originTokenAddress common.Address) (common.Address, error) { + return _Ulxly.Contract.GetTokenWrappedAddress(&_Ulxly.CallOpts, originNetwork, originTokenAddress) +} + +// GlobalExitRootManager is a free data retrieval call binding the contract method 0xd02103ca. +// +// Solidity: function globalExitRootManager() view returns(address) +func (_Ulxly *UlxlyCaller) GlobalExitRootManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "globalExitRootManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GlobalExitRootManager is a free data retrieval call binding the contract method 0xd02103ca. +// +// Solidity: function globalExitRootManager() view returns(address) +func (_Ulxly *UlxlySession) GlobalExitRootManager() (common.Address, error) { + return _Ulxly.Contract.GlobalExitRootManager(&_Ulxly.CallOpts) +} + +// GlobalExitRootManager is a free data retrieval call binding the contract method 0xd02103ca. +// +// Solidity: function globalExitRootManager() view returns(address) +func (_Ulxly *UlxlyCallerSession) GlobalExitRootManager() (common.Address, error) { + return _Ulxly.Contract.GlobalExitRootManager(&_Ulxly.CallOpts) +} + +// IsClaimed is a free data retrieval call binding the contract method 0xcc461632. +// +// Solidity: function isClaimed(uint32 leafIndex, uint32 sourceBridgeNetwork) view returns(bool) +func (_Ulxly *UlxlyCaller) IsClaimed(opts *bind.CallOpts, leafIndex uint32, sourceBridgeNetwork uint32) (bool, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "isClaimed", leafIndex, sourceBridgeNetwork) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsClaimed is a free data retrieval call binding the contract method 0xcc461632. +// +// Solidity: function isClaimed(uint32 leafIndex, uint32 sourceBridgeNetwork) view returns(bool) +func (_Ulxly *UlxlySession) IsClaimed(leafIndex uint32, sourceBridgeNetwork uint32) (bool, error) { + return _Ulxly.Contract.IsClaimed(&_Ulxly.CallOpts, leafIndex, sourceBridgeNetwork) +} + +// IsClaimed is a free data retrieval call binding the contract method 0xcc461632. +// +// Solidity: function isClaimed(uint32 leafIndex, uint32 sourceBridgeNetwork) view returns(bool) +func (_Ulxly *UlxlyCallerSession) IsClaimed(leafIndex uint32, sourceBridgeNetwork uint32) (bool, error) { + return _Ulxly.Contract.IsClaimed(&_Ulxly.CallOpts, leafIndex, sourceBridgeNetwork) +} + +// IsEmergencyState is a free data retrieval call binding the contract method 0x15064c96. +// +// Solidity: function isEmergencyState() view returns(bool) +func (_Ulxly *UlxlyCaller) IsEmergencyState(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "isEmergencyState") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsEmergencyState is a free data retrieval call binding the contract method 0x15064c96. +// +// Solidity: function isEmergencyState() view returns(bool) +func (_Ulxly *UlxlySession) IsEmergencyState() (bool, error) { + return _Ulxly.Contract.IsEmergencyState(&_Ulxly.CallOpts) +} + +// IsEmergencyState is a free data retrieval call binding the contract method 0x15064c96. +// +// Solidity: function isEmergencyState() view returns(bool) +func (_Ulxly *UlxlyCallerSession) IsEmergencyState() (bool, error) { + return _Ulxly.Contract.IsEmergencyState(&_Ulxly.CallOpts) +} + +// LastUpdatedDepositCount is a free data retrieval call binding the contract method 0xbe5831c7. +// +// Solidity: function lastUpdatedDepositCount() view returns(uint32) +func (_Ulxly *UlxlyCaller) LastUpdatedDepositCount(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "lastUpdatedDepositCount") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// LastUpdatedDepositCount is a free data retrieval call binding the contract method 0xbe5831c7. +// +// Solidity: function lastUpdatedDepositCount() view returns(uint32) +func (_Ulxly *UlxlySession) LastUpdatedDepositCount() (uint32, error) { + return _Ulxly.Contract.LastUpdatedDepositCount(&_Ulxly.CallOpts) +} + +// LastUpdatedDepositCount is a free data retrieval call binding the contract method 0xbe5831c7. +// +// Solidity: function lastUpdatedDepositCount() view returns(uint32) +func (_Ulxly *UlxlyCallerSession) LastUpdatedDepositCount() (uint32, error) { + return _Ulxly.Contract.LastUpdatedDepositCount(&_Ulxly.CallOpts) +} + +// NetworkID is a free data retrieval call binding the contract method 0xbab161bf. +// +// Solidity: function networkID() view returns(uint32) +func (_Ulxly *UlxlyCaller) NetworkID(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "networkID") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// NetworkID is a free data retrieval call binding the contract method 0xbab161bf. +// +// Solidity: function networkID() view returns(uint32) +func (_Ulxly *UlxlySession) NetworkID() (uint32, error) { + return _Ulxly.Contract.NetworkID(&_Ulxly.CallOpts) +} + +// NetworkID is a free data retrieval call binding the contract method 0xbab161bf. +// +// Solidity: function networkID() view returns(uint32) +func (_Ulxly *UlxlyCallerSession) NetworkID() (uint32, error) { + return _Ulxly.Contract.NetworkID(&_Ulxly.CallOpts) +} + +// PolygonRollupManager is a free data retrieval call binding the contract method 0x8ed7e3f2. +// +// Solidity: function polygonRollupManager() view returns(address) +func (_Ulxly *UlxlyCaller) PolygonRollupManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "polygonRollupManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PolygonRollupManager is a free data retrieval call binding the contract method 0x8ed7e3f2. +// +// Solidity: function polygonRollupManager() view returns(address) +func (_Ulxly *UlxlySession) PolygonRollupManager() (common.Address, error) { + return _Ulxly.Contract.PolygonRollupManager(&_Ulxly.CallOpts) +} + +// PolygonRollupManager is a free data retrieval call binding the contract method 0x8ed7e3f2. +// +// Solidity: function polygonRollupManager() view returns(address) +func (_Ulxly *UlxlyCallerSession) PolygonRollupManager() (common.Address, error) { + return _Ulxly.Contract.PolygonRollupManager(&_Ulxly.CallOpts) +} + +// PrecalculatedWrapperAddress is a free data retrieval call binding the contract method 0xaaa13cc2. +// +// Solidity: function precalculatedWrapperAddress(uint32 originNetwork, address originTokenAddress, string name, string symbol, uint8 decimals) view returns(address) +func (_Ulxly *UlxlyCaller) PrecalculatedWrapperAddress(opts *bind.CallOpts, originNetwork uint32, originTokenAddress common.Address, name string, symbol string, decimals uint8) (common.Address, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "precalculatedWrapperAddress", originNetwork, originTokenAddress, name, symbol, decimals) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PrecalculatedWrapperAddress is a free data retrieval call binding the contract method 0xaaa13cc2. +// +// Solidity: function precalculatedWrapperAddress(uint32 originNetwork, address originTokenAddress, string name, string symbol, uint8 decimals) view returns(address) +func (_Ulxly *UlxlySession) PrecalculatedWrapperAddress(originNetwork uint32, originTokenAddress common.Address, name string, symbol string, decimals uint8) (common.Address, error) { + return _Ulxly.Contract.PrecalculatedWrapperAddress(&_Ulxly.CallOpts, originNetwork, originTokenAddress, name, symbol, decimals) +} + +// PrecalculatedWrapperAddress is a free data retrieval call binding the contract method 0xaaa13cc2. +// +// Solidity: function precalculatedWrapperAddress(uint32 originNetwork, address originTokenAddress, string name, string symbol, uint8 decimals) view returns(address) +func (_Ulxly *UlxlyCallerSession) PrecalculatedWrapperAddress(originNetwork uint32, originTokenAddress common.Address, name string, symbol string, decimals uint8) (common.Address, error) { + return _Ulxly.Contract.PrecalculatedWrapperAddress(&_Ulxly.CallOpts, originNetwork, originTokenAddress, name, symbol, decimals) +} + +// TokenInfoToWrappedToken is a free data retrieval call binding the contract method 0x81b1c174. +// +// Solidity: function tokenInfoToWrappedToken(bytes32 ) view returns(address) +func (_Ulxly *UlxlyCaller) TokenInfoToWrappedToken(opts *bind.CallOpts, arg0 [32]byte) (common.Address, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "tokenInfoToWrappedToken", arg0) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// TokenInfoToWrappedToken is a free data retrieval call binding the contract method 0x81b1c174. +// +// Solidity: function tokenInfoToWrappedToken(bytes32 ) view returns(address) +func (_Ulxly *UlxlySession) TokenInfoToWrappedToken(arg0 [32]byte) (common.Address, error) { + return _Ulxly.Contract.TokenInfoToWrappedToken(&_Ulxly.CallOpts, arg0) +} + +// TokenInfoToWrappedToken is a free data retrieval call binding the contract method 0x81b1c174. +// +// Solidity: function tokenInfoToWrappedToken(bytes32 ) view returns(address) +func (_Ulxly *UlxlyCallerSession) TokenInfoToWrappedToken(arg0 [32]byte) (common.Address, error) { + return _Ulxly.Contract.TokenInfoToWrappedToken(&_Ulxly.CallOpts, arg0) +} + +// VerifyMerkleProof is a free data retrieval call binding the contract method 0xfb570834. +// +// Solidity: function verifyMerkleProof(bytes32 leafHash, bytes32[32] smtProof, uint32 index, bytes32 root) pure returns(bool) +func (_Ulxly *UlxlyCaller) VerifyMerkleProof(opts *bind.CallOpts, leafHash [32]byte, smtProof [32][32]byte, index uint32, root [32]byte) (bool, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "verifyMerkleProof", leafHash, smtProof, index, root) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// VerifyMerkleProof is a free data retrieval call binding the contract method 0xfb570834. +// +// Solidity: function verifyMerkleProof(bytes32 leafHash, bytes32[32] smtProof, uint32 index, bytes32 root) pure returns(bool) +func (_Ulxly *UlxlySession) VerifyMerkleProof(leafHash [32]byte, smtProof [32][32]byte, index uint32, root [32]byte) (bool, error) { + return _Ulxly.Contract.VerifyMerkleProof(&_Ulxly.CallOpts, leafHash, smtProof, index, root) +} + +// VerifyMerkleProof is a free data retrieval call binding the contract method 0xfb570834. +// +// Solidity: function verifyMerkleProof(bytes32 leafHash, bytes32[32] smtProof, uint32 index, bytes32 root) pure returns(bool) +func (_Ulxly *UlxlyCallerSession) VerifyMerkleProof(leafHash [32]byte, smtProof [32][32]byte, index uint32, root [32]byte) (bool, error) { + return _Ulxly.Contract.VerifyMerkleProof(&_Ulxly.CallOpts, leafHash, smtProof, index, root) +} + +// WrappedTokenToTokenInfo is a free data retrieval call binding the contract method 0x318aee3d. +// +// Solidity: function wrappedTokenToTokenInfo(address ) view returns(uint32 originNetwork, address originTokenAddress) +func (_Ulxly *UlxlyCaller) WrappedTokenToTokenInfo(opts *bind.CallOpts, arg0 common.Address) (struct { + OriginNetwork uint32 + OriginTokenAddress common.Address +}, error) { + var out []interface{} + err := _Ulxly.contract.Call(opts, &out, "wrappedTokenToTokenInfo", arg0) + + outstruct := new(struct { + OriginNetwork uint32 + OriginTokenAddress common.Address + }) + if err != nil { + return *outstruct, err + } + + outstruct.OriginNetwork = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.OriginTokenAddress = *abi.ConvertType(out[1], new(common.Address)).(*common.Address) + + return *outstruct, err + +} + +// WrappedTokenToTokenInfo is a free data retrieval call binding the contract method 0x318aee3d. +// +// Solidity: function wrappedTokenToTokenInfo(address ) view returns(uint32 originNetwork, address originTokenAddress) +func (_Ulxly *UlxlySession) WrappedTokenToTokenInfo(arg0 common.Address) (struct { + OriginNetwork uint32 + OriginTokenAddress common.Address +}, error) { + return _Ulxly.Contract.WrappedTokenToTokenInfo(&_Ulxly.CallOpts, arg0) +} + +// WrappedTokenToTokenInfo is a free data retrieval call binding the contract method 0x318aee3d. +// +// Solidity: function wrappedTokenToTokenInfo(address ) view returns(uint32 originNetwork, address originTokenAddress) +func (_Ulxly *UlxlyCallerSession) WrappedTokenToTokenInfo(arg0 common.Address) (struct { + OriginNetwork uint32 + OriginTokenAddress common.Address +}, error) { + return _Ulxly.Contract.WrappedTokenToTokenInfo(&_Ulxly.CallOpts, arg0) +} + +// ActivateEmergencyState is a paid mutator transaction binding the contract method 0x2072f6c5. +// +// Solidity: function activateEmergencyState() returns() +func (_Ulxly *UlxlyTransactor) ActivateEmergencyState(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Ulxly.contract.Transact(opts, "activateEmergencyState") +} + +// ActivateEmergencyState is a paid mutator transaction binding the contract method 0x2072f6c5. +// +// Solidity: function activateEmergencyState() returns() +func (_Ulxly *UlxlySession) ActivateEmergencyState() (*types.Transaction, error) { + return _Ulxly.Contract.ActivateEmergencyState(&_Ulxly.TransactOpts) +} + +// ActivateEmergencyState is a paid mutator transaction binding the contract method 0x2072f6c5. +// +// Solidity: function activateEmergencyState() returns() +func (_Ulxly *UlxlyTransactorSession) ActivateEmergencyState() (*types.Transaction, error) { + return _Ulxly.Contract.ActivateEmergencyState(&_Ulxly.TransactOpts) +} + +// BridgeAsset is a paid mutator transaction binding the contract method 0xcd586579. +// +// Solidity: function bridgeAsset(uint32 destinationNetwork, address destinationAddress, uint256 amount, address token, bool forceUpdateGlobalExitRoot, bytes permitData) payable returns() +func (_Ulxly *UlxlyTransactor) BridgeAsset(opts *bind.TransactOpts, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, token common.Address, forceUpdateGlobalExitRoot bool, permitData []byte) (*types.Transaction, error) { + return _Ulxly.contract.Transact(opts, "bridgeAsset", destinationNetwork, destinationAddress, amount, token, forceUpdateGlobalExitRoot, permitData) +} + +// BridgeAsset is a paid mutator transaction binding the contract method 0xcd586579. +// +// Solidity: function bridgeAsset(uint32 destinationNetwork, address destinationAddress, uint256 amount, address token, bool forceUpdateGlobalExitRoot, bytes permitData) payable returns() +func (_Ulxly *UlxlySession) BridgeAsset(destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, token common.Address, forceUpdateGlobalExitRoot bool, permitData []byte) (*types.Transaction, error) { + return _Ulxly.Contract.BridgeAsset(&_Ulxly.TransactOpts, destinationNetwork, destinationAddress, amount, token, forceUpdateGlobalExitRoot, permitData) +} + +// BridgeAsset is a paid mutator transaction binding the contract method 0xcd586579. +// +// Solidity: function bridgeAsset(uint32 destinationNetwork, address destinationAddress, uint256 amount, address token, bool forceUpdateGlobalExitRoot, bytes permitData) payable returns() +func (_Ulxly *UlxlyTransactorSession) BridgeAsset(destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, token common.Address, forceUpdateGlobalExitRoot bool, permitData []byte) (*types.Transaction, error) { + return _Ulxly.Contract.BridgeAsset(&_Ulxly.TransactOpts, destinationNetwork, destinationAddress, amount, token, forceUpdateGlobalExitRoot, permitData) +} + +// BridgeMessage is a paid mutator transaction binding the contract method 0x240ff378. +// +// Solidity: function bridgeMessage(uint32 destinationNetwork, address destinationAddress, bool forceUpdateGlobalExitRoot, bytes metadata) payable returns() +func (_Ulxly *UlxlyTransactor) BridgeMessage(opts *bind.TransactOpts, destinationNetwork uint32, destinationAddress common.Address, forceUpdateGlobalExitRoot bool, metadata []byte) (*types.Transaction, error) { + return _Ulxly.contract.Transact(opts, "bridgeMessage", destinationNetwork, destinationAddress, forceUpdateGlobalExitRoot, metadata) +} + +// BridgeMessage is a paid mutator transaction binding the contract method 0x240ff378. +// +// Solidity: function bridgeMessage(uint32 destinationNetwork, address destinationAddress, bool forceUpdateGlobalExitRoot, bytes metadata) payable returns() +func (_Ulxly *UlxlySession) BridgeMessage(destinationNetwork uint32, destinationAddress common.Address, forceUpdateGlobalExitRoot bool, metadata []byte) (*types.Transaction, error) { + return _Ulxly.Contract.BridgeMessage(&_Ulxly.TransactOpts, destinationNetwork, destinationAddress, forceUpdateGlobalExitRoot, metadata) +} + +// BridgeMessage is a paid mutator transaction binding the contract method 0x240ff378. +// +// Solidity: function bridgeMessage(uint32 destinationNetwork, address destinationAddress, bool forceUpdateGlobalExitRoot, bytes metadata) payable returns() +func (_Ulxly *UlxlyTransactorSession) BridgeMessage(destinationNetwork uint32, destinationAddress common.Address, forceUpdateGlobalExitRoot bool, metadata []byte) (*types.Transaction, error) { + return _Ulxly.Contract.BridgeMessage(&_Ulxly.TransactOpts, destinationNetwork, destinationAddress, forceUpdateGlobalExitRoot, metadata) +} + +// BridgeMessageWETH is a paid mutator transaction binding the contract method 0xb8b284d0. +// +// Solidity: function bridgeMessageWETH(uint32 destinationNetwork, address destinationAddress, uint256 amountWETH, bool forceUpdateGlobalExitRoot, bytes metadata) returns() +func (_Ulxly *UlxlyTransactor) BridgeMessageWETH(opts *bind.TransactOpts, destinationNetwork uint32, destinationAddress common.Address, amountWETH *big.Int, forceUpdateGlobalExitRoot bool, metadata []byte) (*types.Transaction, error) { + return _Ulxly.contract.Transact(opts, "bridgeMessageWETH", destinationNetwork, destinationAddress, amountWETH, forceUpdateGlobalExitRoot, metadata) +} + +// BridgeMessageWETH is a paid mutator transaction binding the contract method 0xb8b284d0. +// +// Solidity: function bridgeMessageWETH(uint32 destinationNetwork, address destinationAddress, uint256 amountWETH, bool forceUpdateGlobalExitRoot, bytes metadata) returns() +func (_Ulxly *UlxlySession) BridgeMessageWETH(destinationNetwork uint32, destinationAddress common.Address, amountWETH *big.Int, forceUpdateGlobalExitRoot bool, metadata []byte) (*types.Transaction, error) { + return _Ulxly.Contract.BridgeMessageWETH(&_Ulxly.TransactOpts, destinationNetwork, destinationAddress, amountWETH, forceUpdateGlobalExitRoot, metadata) +} + +// BridgeMessageWETH is a paid mutator transaction binding the contract method 0xb8b284d0. +// +// Solidity: function bridgeMessageWETH(uint32 destinationNetwork, address destinationAddress, uint256 amountWETH, bool forceUpdateGlobalExitRoot, bytes metadata) returns() +func (_Ulxly *UlxlyTransactorSession) BridgeMessageWETH(destinationNetwork uint32, destinationAddress common.Address, amountWETH *big.Int, forceUpdateGlobalExitRoot bool, metadata []byte) (*types.Transaction, error) { + return _Ulxly.Contract.BridgeMessageWETH(&_Ulxly.TransactOpts, destinationNetwork, destinationAddress, amountWETH, forceUpdateGlobalExitRoot, metadata) +} + +// ClaimAsset is a paid mutator transaction binding the contract method 0xccaa2d11. +// +// Solidity: function claimAsset(bytes32[32] smtProofLocalExitRoot, bytes32[32] smtProofRollupExitRoot, uint256 globalIndex, bytes32 mainnetExitRoot, bytes32 rollupExitRoot, uint32 originNetwork, address originTokenAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata) returns() +func (_Ulxly *UlxlyTransactor) ClaimAsset(opts *bind.TransactOpts, smtProofLocalExitRoot [32][32]byte, smtProofRollupExitRoot [32][32]byte, globalIndex *big.Int, mainnetExitRoot [32]byte, rollupExitRoot [32]byte, originNetwork uint32, originTokenAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadata []byte) (*types.Transaction, error) { + return _Ulxly.contract.Transact(opts, "claimAsset", smtProofLocalExitRoot, smtProofRollupExitRoot, globalIndex, mainnetExitRoot, rollupExitRoot, originNetwork, originTokenAddress, destinationNetwork, destinationAddress, amount, metadata) +} + +// ClaimAsset is a paid mutator transaction binding the contract method 0xccaa2d11. +// +// Solidity: function claimAsset(bytes32[32] smtProofLocalExitRoot, bytes32[32] smtProofRollupExitRoot, uint256 globalIndex, bytes32 mainnetExitRoot, bytes32 rollupExitRoot, uint32 originNetwork, address originTokenAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata) returns() +func (_Ulxly *UlxlySession) ClaimAsset(smtProofLocalExitRoot [32][32]byte, smtProofRollupExitRoot [32][32]byte, globalIndex *big.Int, mainnetExitRoot [32]byte, rollupExitRoot [32]byte, originNetwork uint32, originTokenAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadata []byte) (*types.Transaction, error) { + return _Ulxly.Contract.ClaimAsset(&_Ulxly.TransactOpts, smtProofLocalExitRoot, smtProofRollupExitRoot, globalIndex, mainnetExitRoot, rollupExitRoot, originNetwork, originTokenAddress, destinationNetwork, destinationAddress, amount, metadata) +} + +// ClaimAsset is a paid mutator transaction binding the contract method 0xccaa2d11. +// +// Solidity: function claimAsset(bytes32[32] smtProofLocalExitRoot, bytes32[32] smtProofRollupExitRoot, uint256 globalIndex, bytes32 mainnetExitRoot, bytes32 rollupExitRoot, uint32 originNetwork, address originTokenAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata) returns() +func (_Ulxly *UlxlyTransactorSession) ClaimAsset(smtProofLocalExitRoot [32][32]byte, smtProofRollupExitRoot [32][32]byte, globalIndex *big.Int, mainnetExitRoot [32]byte, rollupExitRoot [32]byte, originNetwork uint32, originTokenAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadata []byte) (*types.Transaction, error) { + return _Ulxly.Contract.ClaimAsset(&_Ulxly.TransactOpts, smtProofLocalExitRoot, smtProofRollupExitRoot, globalIndex, mainnetExitRoot, rollupExitRoot, originNetwork, originTokenAddress, destinationNetwork, destinationAddress, amount, metadata) +} + +// ClaimMessage is a paid mutator transaction binding the contract method 0xf5efcd79. +// +// Solidity: function claimMessage(bytes32[32] smtProofLocalExitRoot, bytes32[32] smtProofRollupExitRoot, uint256 globalIndex, bytes32 mainnetExitRoot, bytes32 rollupExitRoot, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata) returns() +func (_Ulxly *UlxlyTransactor) ClaimMessage(opts *bind.TransactOpts, smtProofLocalExitRoot [32][32]byte, smtProofRollupExitRoot [32][32]byte, globalIndex *big.Int, mainnetExitRoot [32]byte, rollupExitRoot [32]byte, originNetwork uint32, originAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadata []byte) (*types.Transaction, error) { + return _Ulxly.contract.Transact(opts, "claimMessage", smtProofLocalExitRoot, smtProofRollupExitRoot, globalIndex, mainnetExitRoot, rollupExitRoot, originNetwork, originAddress, destinationNetwork, destinationAddress, amount, metadata) +} + +// ClaimMessage is a paid mutator transaction binding the contract method 0xf5efcd79. +// +// Solidity: function claimMessage(bytes32[32] smtProofLocalExitRoot, bytes32[32] smtProofRollupExitRoot, uint256 globalIndex, bytes32 mainnetExitRoot, bytes32 rollupExitRoot, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata) returns() +func (_Ulxly *UlxlySession) ClaimMessage(smtProofLocalExitRoot [32][32]byte, smtProofRollupExitRoot [32][32]byte, globalIndex *big.Int, mainnetExitRoot [32]byte, rollupExitRoot [32]byte, originNetwork uint32, originAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadata []byte) (*types.Transaction, error) { + return _Ulxly.Contract.ClaimMessage(&_Ulxly.TransactOpts, smtProofLocalExitRoot, smtProofRollupExitRoot, globalIndex, mainnetExitRoot, rollupExitRoot, originNetwork, originAddress, destinationNetwork, destinationAddress, amount, metadata) +} + +// ClaimMessage is a paid mutator transaction binding the contract method 0xf5efcd79. +// +// Solidity: function claimMessage(bytes32[32] smtProofLocalExitRoot, bytes32[32] smtProofRollupExitRoot, uint256 globalIndex, bytes32 mainnetExitRoot, bytes32 rollupExitRoot, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata) returns() +func (_Ulxly *UlxlyTransactorSession) ClaimMessage(smtProofLocalExitRoot [32][32]byte, smtProofRollupExitRoot [32][32]byte, globalIndex *big.Int, mainnetExitRoot [32]byte, rollupExitRoot [32]byte, originNetwork uint32, originAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadata []byte) (*types.Transaction, error) { + return _Ulxly.Contract.ClaimMessage(&_Ulxly.TransactOpts, smtProofLocalExitRoot, smtProofRollupExitRoot, globalIndex, mainnetExitRoot, rollupExitRoot, originNetwork, originAddress, destinationNetwork, destinationAddress, amount, metadata) +} + +// DeactivateEmergencyState is a paid mutator transaction binding the contract method 0xdbc16976. +// +// Solidity: function deactivateEmergencyState() returns() +func (_Ulxly *UlxlyTransactor) DeactivateEmergencyState(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Ulxly.contract.Transact(opts, "deactivateEmergencyState") +} + +// DeactivateEmergencyState is a paid mutator transaction binding the contract method 0xdbc16976. +// +// Solidity: function deactivateEmergencyState() returns() +func (_Ulxly *UlxlySession) DeactivateEmergencyState() (*types.Transaction, error) { + return _Ulxly.Contract.DeactivateEmergencyState(&_Ulxly.TransactOpts) +} + +// DeactivateEmergencyState is a paid mutator transaction binding the contract method 0xdbc16976. +// +// Solidity: function deactivateEmergencyState() returns() +func (_Ulxly *UlxlyTransactorSession) DeactivateEmergencyState() (*types.Transaction, error) { + return _Ulxly.Contract.DeactivateEmergencyState(&_Ulxly.TransactOpts) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf811bff7. +// +// Solidity: function initialize(uint32 _networkID, address _gasTokenAddress, uint32 _gasTokenNetwork, address _globalExitRootManager, address _polygonRollupManager, bytes _gasTokenMetadata) returns() +func (_Ulxly *UlxlyTransactor) Initialize(opts *bind.TransactOpts, _networkID uint32, _gasTokenAddress common.Address, _gasTokenNetwork uint32, _globalExitRootManager common.Address, _polygonRollupManager common.Address, _gasTokenMetadata []byte) (*types.Transaction, error) { + return _Ulxly.contract.Transact(opts, "initialize", _networkID, _gasTokenAddress, _gasTokenNetwork, _globalExitRootManager, _polygonRollupManager, _gasTokenMetadata) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf811bff7. +// +// Solidity: function initialize(uint32 _networkID, address _gasTokenAddress, uint32 _gasTokenNetwork, address _globalExitRootManager, address _polygonRollupManager, bytes _gasTokenMetadata) returns() +func (_Ulxly *UlxlySession) Initialize(_networkID uint32, _gasTokenAddress common.Address, _gasTokenNetwork uint32, _globalExitRootManager common.Address, _polygonRollupManager common.Address, _gasTokenMetadata []byte) (*types.Transaction, error) { + return _Ulxly.Contract.Initialize(&_Ulxly.TransactOpts, _networkID, _gasTokenAddress, _gasTokenNetwork, _globalExitRootManager, _polygonRollupManager, _gasTokenMetadata) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf811bff7. +// +// Solidity: function initialize(uint32 _networkID, address _gasTokenAddress, uint32 _gasTokenNetwork, address _globalExitRootManager, address _polygonRollupManager, bytes _gasTokenMetadata) returns() +func (_Ulxly *UlxlyTransactorSession) Initialize(_networkID uint32, _gasTokenAddress common.Address, _gasTokenNetwork uint32, _globalExitRootManager common.Address, _polygonRollupManager common.Address, _gasTokenMetadata []byte) (*types.Transaction, error) { + return _Ulxly.Contract.Initialize(&_Ulxly.TransactOpts, _networkID, _gasTokenAddress, _gasTokenNetwork, _globalExitRootManager, _polygonRollupManager, _gasTokenMetadata) +} + +// UpdateGlobalExitRoot is a paid mutator transaction binding the contract method 0x79e2cf97. +// +// Solidity: function updateGlobalExitRoot() returns() +func (_Ulxly *UlxlyTransactor) UpdateGlobalExitRoot(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Ulxly.contract.Transact(opts, "updateGlobalExitRoot") +} + +// UpdateGlobalExitRoot is a paid mutator transaction binding the contract method 0x79e2cf97. +// +// Solidity: function updateGlobalExitRoot() returns() +func (_Ulxly *UlxlySession) UpdateGlobalExitRoot() (*types.Transaction, error) { + return _Ulxly.Contract.UpdateGlobalExitRoot(&_Ulxly.TransactOpts) +} + +// UpdateGlobalExitRoot is a paid mutator transaction binding the contract method 0x79e2cf97. +// +// Solidity: function updateGlobalExitRoot() returns() +func (_Ulxly *UlxlyTransactorSession) UpdateGlobalExitRoot() (*types.Transaction, error) { + return _Ulxly.Contract.UpdateGlobalExitRoot(&_Ulxly.TransactOpts) +} + +// UlxlyBridgeEventIterator is returned from FilterBridgeEvent and is used to iterate over the raw logs and unpacked data for BridgeEvent events raised by the Ulxly contract. +type UlxlyBridgeEventIterator struct { + Event *UlxlyBridgeEvent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UlxlyBridgeEventIterator) 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(UlxlyBridgeEvent) + 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(UlxlyBridgeEvent) + 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 *UlxlyBridgeEventIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UlxlyBridgeEventIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UlxlyBridgeEvent represents a BridgeEvent event raised by the Ulxly contract. +type UlxlyBridgeEvent struct { + LeafType uint8 + OriginNetwork uint32 + OriginAddress common.Address + DestinationNetwork uint32 + DestinationAddress common.Address + Amount *big.Int + Metadata []byte + DepositCount uint32 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBridgeEvent is a free log retrieval operation binding the contract event 0x501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b. +// +// Solidity: event BridgeEvent(uint8 leafType, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata, uint32 depositCount) +func (_Ulxly *UlxlyFilterer) FilterBridgeEvent(opts *bind.FilterOpts) (*UlxlyBridgeEventIterator, error) { + + logs, sub, err := _Ulxly.contract.FilterLogs(opts, "BridgeEvent") + if err != nil { + return nil, err + } + return &UlxlyBridgeEventIterator{contract: _Ulxly.contract, event: "BridgeEvent", logs: logs, sub: sub}, nil +} + +// WatchBridgeEvent is a free log subscription operation binding the contract event 0x501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b. +// +// Solidity: event BridgeEvent(uint8 leafType, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata, uint32 depositCount) +func (_Ulxly *UlxlyFilterer) WatchBridgeEvent(opts *bind.WatchOpts, sink chan<- *UlxlyBridgeEvent) (event.Subscription, error) { + + logs, sub, err := _Ulxly.contract.WatchLogs(opts, "BridgeEvent") + 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(UlxlyBridgeEvent) + if err := _Ulxly.contract.UnpackLog(event, "BridgeEvent", 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 +} + +// ParseBridgeEvent is a log parse operation binding the contract event 0x501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b. +// +// Solidity: event BridgeEvent(uint8 leafType, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata, uint32 depositCount) +func (_Ulxly *UlxlyFilterer) ParseBridgeEvent(log types.Log) (*UlxlyBridgeEvent, error) { + event := new(UlxlyBridgeEvent) + if err := _Ulxly.contract.UnpackLog(event, "BridgeEvent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UlxlyClaimEventIterator is returned from FilterClaimEvent and is used to iterate over the raw logs and unpacked data for ClaimEvent events raised by the Ulxly contract. +type UlxlyClaimEventIterator struct { + Event *UlxlyClaimEvent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UlxlyClaimEventIterator) 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(UlxlyClaimEvent) + 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(UlxlyClaimEvent) + 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 *UlxlyClaimEventIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UlxlyClaimEventIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UlxlyClaimEvent represents a ClaimEvent event raised by the Ulxly contract. +type UlxlyClaimEvent struct { + GlobalIndex *big.Int + OriginNetwork uint32 + OriginAddress common.Address + DestinationAddress common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterClaimEvent is a free log retrieval operation binding the contract event 0x1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d. +// +// Solidity: event ClaimEvent(uint256 globalIndex, uint32 originNetwork, address originAddress, address destinationAddress, uint256 amount) +func (_Ulxly *UlxlyFilterer) FilterClaimEvent(opts *bind.FilterOpts) (*UlxlyClaimEventIterator, error) { + + logs, sub, err := _Ulxly.contract.FilterLogs(opts, "ClaimEvent") + if err != nil { + return nil, err + } + return &UlxlyClaimEventIterator{contract: _Ulxly.contract, event: "ClaimEvent", logs: logs, sub: sub}, nil +} + +// WatchClaimEvent is a free log subscription operation binding the contract event 0x1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d. +// +// Solidity: event ClaimEvent(uint256 globalIndex, uint32 originNetwork, address originAddress, address destinationAddress, uint256 amount) +func (_Ulxly *UlxlyFilterer) WatchClaimEvent(opts *bind.WatchOpts, sink chan<- *UlxlyClaimEvent) (event.Subscription, error) { + + logs, sub, err := _Ulxly.contract.WatchLogs(opts, "ClaimEvent") + 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(UlxlyClaimEvent) + if err := _Ulxly.contract.UnpackLog(event, "ClaimEvent", 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 +} + +// ParseClaimEvent is a log parse operation binding the contract event 0x1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d. +// +// Solidity: event ClaimEvent(uint256 globalIndex, uint32 originNetwork, address originAddress, address destinationAddress, uint256 amount) +func (_Ulxly *UlxlyFilterer) ParseClaimEvent(log types.Log) (*UlxlyClaimEvent, error) { + event := new(UlxlyClaimEvent) + if err := _Ulxly.contract.UnpackLog(event, "ClaimEvent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UlxlyEmergencyStateActivatedIterator is returned from FilterEmergencyStateActivated and is used to iterate over the raw logs and unpacked data for EmergencyStateActivated events raised by the Ulxly contract. +type UlxlyEmergencyStateActivatedIterator struct { + Event *UlxlyEmergencyStateActivated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UlxlyEmergencyStateActivatedIterator) 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(UlxlyEmergencyStateActivated) + 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(UlxlyEmergencyStateActivated) + 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 *UlxlyEmergencyStateActivatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UlxlyEmergencyStateActivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UlxlyEmergencyStateActivated represents a EmergencyStateActivated event raised by the Ulxly contract. +type UlxlyEmergencyStateActivated struct { + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEmergencyStateActivated is a free log retrieval operation binding the contract event 0x2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a5497. +// +// Solidity: event EmergencyStateActivated() +func (_Ulxly *UlxlyFilterer) FilterEmergencyStateActivated(opts *bind.FilterOpts) (*UlxlyEmergencyStateActivatedIterator, error) { + + logs, sub, err := _Ulxly.contract.FilterLogs(opts, "EmergencyStateActivated") + if err != nil { + return nil, err + } + return &UlxlyEmergencyStateActivatedIterator{contract: _Ulxly.contract, event: "EmergencyStateActivated", logs: logs, sub: sub}, nil +} + +// WatchEmergencyStateActivated is a free log subscription operation binding the contract event 0x2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a5497. +// +// Solidity: event EmergencyStateActivated() +func (_Ulxly *UlxlyFilterer) WatchEmergencyStateActivated(opts *bind.WatchOpts, sink chan<- *UlxlyEmergencyStateActivated) (event.Subscription, error) { + + logs, sub, err := _Ulxly.contract.WatchLogs(opts, "EmergencyStateActivated") + 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(UlxlyEmergencyStateActivated) + if err := _Ulxly.contract.UnpackLog(event, "EmergencyStateActivated", 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 +} + +// ParseEmergencyStateActivated is a log parse operation binding the contract event 0x2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a5497. +// +// Solidity: event EmergencyStateActivated() +func (_Ulxly *UlxlyFilterer) ParseEmergencyStateActivated(log types.Log) (*UlxlyEmergencyStateActivated, error) { + event := new(UlxlyEmergencyStateActivated) + if err := _Ulxly.contract.UnpackLog(event, "EmergencyStateActivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UlxlyEmergencyStateDeactivatedIterator is returned from FilterEmergencyStateDeactivated and is used to iterate over the raw logs and unpacked data for EmergencyStateDeactivated events raised by the Ulxly contract. +type UlxlyEmergencyStateDeactivatedIterator struct { + Event *UlxlyEmergencyStateDeactivated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UlxlyEmergencyStateDeactivatedIterator) 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(UlxlyEmergencyStateDeactivated) + 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(UlxlyEmergencyStateDeactivated) + 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 *UlxlyEmergencyStateDeactivatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UlxlyEmergencyStateDeactivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UlxlyEmergencyStateDeactivated represents a EmergencyStateDeactivated event raised by the Ulxly contract. +type UlxlyEmergencyStateDeactivated struct { + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEmergencyStateDeactivated is a free log retrieval operation binding the contract event 0x1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b3. +// +// Solidity: event EmergencyStateDeactivated() +func (_Ulxly *UlxlyFilterer) FilterEmergencyStateDeactivated(opts *bind.FilterOpts) (*UlxlyEmergencyStateDeactivatedIterator, error) { + + logs, sub, err := _Ulxly.contract.FilterLogs(opts, "EmergencyStateDeactivated") + if err != nil { + return nil, err + } + return &UlxlyEmergencyStateDeactivatedIterator{contract: _Ulxly.contract, event: "EmergencyStateDeactivated", logs: logs, sub: sub}, nil +} + +// WatchEmergencyStateDeactivated is a free log subscription operation binding the contract event 0x1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b3. +// +// Solidity: event EmergencyStateDeactivated() +func (_Ulxly *UlxlyFilterer) WatchEmergencyStateDeactivated(opts *bind.WatchOpts, sink chan<- *UlxlyEmergencyStateDeactivated) (event.Subscription, error) { + + logs, sub, err := _Ulxly.contract.WatchLogs(opts, "EmergencyStateDeactivated") + 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(UlxlyEmergencyStateDeactivated) + if err := _Ulxly.contract.UnpackLog(event, "EmergencyStateDeactivated", 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 +} + +// ParseEmergencyStateDeactivated is a log parse operation binding the contract event 0x1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b3. +// +// Solidity: event EmergencyStateDeactivated() +func (_Ulxly *UlxlyFilterer) ParseEmergencyStateDeactivated(log types.Log) (*UlxlyEmergencyStateDeactivated, error) { + event := new(UlxlyEmergencyStateDeactivated) + if err := _Ulxly.contract.UnpackLog(event, "EmergencyStateDeactivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UlxlyInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Ulxly contract. +type UlxlyInitializedIterator struct { + Event *UlxlyInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UlxlyInitializedIterator) 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(UlxlyInitialized) + 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(UlxlyInitialized) + 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 *UlxlyInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UlxlyInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UlxlyInitialized represents a Initialized event raised by the Ulxly contract. +type UlxlyInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Ulxly *UlxlyFilterer) FilterInitialized(opts *bind.FilterOpts) (*UlxlyInitializedIterator, error) { + + logs, sub, err := _Ulxly.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &UlxlyInitializedIterator{contract: _Ulxly.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Ulxly *UlxlyFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *UlxlyInitialized) (event.Subscription, error) { + + logs, sub, err := _Ulxly.contract.WatchLogs(opts, "Initialized") + 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(UlxlyInitialized) + if err := _Ulxly.contract.UnpackLog(event, "Initialized", 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 +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Ulxly *UlxlyFilterer) ParseInitialized(log types.Log) (*UlxlyInitialized, error) { + event := new(UlxlyInitialized) + if err := _Ulxly.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UlxlyNewWrappedTokenIterator is returned from FilterNewWrappedToken and is used to iterate over the raw logs and unpacked data for NewWrappedToken events raised by the Ulxly contract. +type UlxlyNewWrappedTokenIterator struct { + Event *UlxlyNewWrappedToken // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UlxlyNewWrappedTokenIterator) 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(UlxlyNewWrappedToken) + 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(UlxlyNewWrappedToken) + 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 *UlxlyNewWrappedTokenIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UlxlyNewWrappedTokenIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UlxlyNewWrappedToken represents a NewWrappedToken event raised by the Ulxly contract. +type UlxlyNewWrappedToken struct { + OriginNetwork uint32 + OriginTokenAddress common.Address + WrappedTokenAddress common.Address + Metadata []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNewWrappedToken is a free log retrieval operation binding the contract event 0x490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a39. +// +// Solidity: event NewWrappedToken(uint32 originNetwork, address originTokenAddress, address wrappedTokenAddress, bytes metadata) +func (_Ulxly *UlxlyFilterer) FilterNewWrappedToken(opts *bind.FilterOpts) (*UlxlyNewWrappedTokenIterator, error) { + + logs, sub, err := _Ulxly.contract.FilterLogs(opts, "NewWrappedToken") + if err != nil { + return nil, err + } + return &UlxlyNewWrappedTokenIterator{contract: _Ulxly.contract, event: "NewWrappedToken", logs: logs, sub: sub}, nil +} + +// WatchNewWrappedToken is a free log subscription operation binding the contract event 0x490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a39. +// +// Solidity: event NewWrappedToken(uint32 originNetwork, address originTokenAddress, address wrappedTokenAddress, bytes metadata) +func (_Ulxly *UlxlyFilterer) WatchNewWrappedToken(opts *bind.WatchOpts, sink chan<- *UlxlyNewWrappedToken) (event.Subscription, error) { + + logs, sub, err := _Ulxly.contract.WatchLogs(opts, "NewWrappedToken") + 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(UlxlyNewWrappedToken) + if err := _Ulxly.contract.UnpackLog(event, "NewWrappedToken", 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 +} + +// ParseNewWrappedToken is a log parse operation binding the contract event 0x490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a39. +// +// Solidity: event NewWrappedToken(uint32 originNetwork, address originTokenAddress, address wrappedTokenAddress, bytes metadata) +func (_Ulxly *UlxlyFilterer) ParseNewWrappedToken(log types.Log) (*UlxlyNewWrappedToken, error) { + event := new(UlxlyNewWrappedToken) + if err := _Ulxly.contract.UnpackLog(event, "NewWrappedToken", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/cmd/root.go b/cmd/root.go index 2e5ae918..b8c7f06e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + "github.com/maticnetwork/polygon-cli/cmd/ulxly" "os" "github.com/maticnetwork/polygon-cli/cmd/fork" @@ -122,6 +123,7 @@ func NewPolycliCommand() *cobra.Command { parseethwallet.ParseETHWalletCmd, rpcfuzz.RPCFuzzCmd, signer.SignerCmd, + ulxly.ULxLyCmd, version.VersionCmd, wallet.WalletCmd, ) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go new file mode 100644 index 00000000..7bad8031 --- /dev/null +++ b/cmd/ulxly/ulxly.go @@ -0,0 +1,95 @@ +package ulxly + +import ( + "encoding/json" + "fmt" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + ethrpc "github.com/ethereum/go-ethereum/rpc" + "github.com/maticnetwork/polygon-cli/bindings/ulxly" + "github.com/rs/zerolog/log" + "github.com/spf13/cobra" +) + +type uLxLyArgs struct { + FromBlock *int64 + ToBlock *int64 + RPCURL *string + BridgeAddress *string +} + +var ulxlyInputArgs uLxLyArgs + +var ULxLyCmd = &cobra.Command{ + Use: "ulxly", + Short: "Utilities for interacting with the lxly bridge", + Long: "TODO", + Args: cobra.NoArgs, +} + +var DepositsCmd = &cobra.Command{ + Use: "deposits", + Short: "get a range of deposits", + Long: "TODO", + Args: cobra.NoArgs, + PreRunE: checkDepositArgs, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := cmd.Context() + // Dial the Ethereum RPC server. + rpc, err := ethrpc.DialContext(ctx, *ulxlyInputArgs.RPCURL) + if err != nil { + log.Error().Err(err).Msg("Unable to dial rpc") + return err + } + defer rpc.Close() + ec := ethclient.NewClient(rpc) + bridge, err := ulxly.NewUlxly(common.HexToAddress(*ulxlyInputArgs.BridgeAddress), ec) + if err != nil { + return err + } + fromBlock := uint64(*ulxlyInputArgs.FromBlock) + toBlock := uint64(*ulxlyInputArgs.ToBlock) + opts := bind.FilterOpts{ + Start: fromBlock, + End: &toBlock, + Context: ctx, + } + evtIterator, err := bridge.FilterBridgeEvent(&opts) + if err != nil { + return err + } + defer evtIterator.Close() + for evtIterator.Next() { + evt := evtIterator.Event + log.Info().Uint32("deposit", evt.DepositCount).Msg("Found Deposit") + jBytes, err := json.Marshal(evt) + if err != nil { + return err + } + fmt.Println(string(jBytes)) + } + return nil + }, +} + +func checkDepositArgs(cmd *cobra.Command, args []string) error { + if *ulxlyInputArgs.BridgeAddress == "" { + return fmt.Errorf("please provide the bridge address") + } + return nil +} + +func init() { + ULxLyCmd.AddCommand(DepositsCmd) + // - When blockNr is -1 the chain pending header is returned. + // - When blockNr is -2 the chain latest header is returned. + // - When blockNr is -3 the chain finalized header is returned. + // - When blockNr is -4 the chain safe header is returned. + ulxlyInputArgs.FromBlock = DepositsCmd.PersistentFlags().Int64("from-block", 0, "The block height to start query at.") + ulxlyInputArgs.ToBlock = DepositsCmd.PersistentFlags().Int64("to-block", -2, "The block height to start query at.") + ulxlyInputArgs.RPCURL = DepositsCmd.PersistentFlags().String("rpc-url", "http://127.0.0.1:8545", "The RPC to query for events") + + ulxlyInputArgs.BridgeAddress = DepositsCmd.Flags().String("bridge-address", "", "The address of the lxly bridge") + +} diff --git a/contracts/Makefile b/contracts/Makefile index fb841119..498e0d54 100644 --- a/contracts/Makefile +++ b/contracts/Makefile @@ -43,5 +43,13 @@ gen-tokens-go-bindings: ## Generate go bindings for the tokens contracts. abigen --abi ../bindings/tokens/ERC721.abi --bin ../bindings/tokens/ERC721.bin --pkg tokens --type ERC721 --out ../bindings/tokens/ERC721.go @echo "✅ tokens/ERC721.go generated" +.PHONY: gen-ulxly-go-bindings +gen-ulxly-go-bindings: + mkdir -p ../bindings/ulxly/ + cat ./out/PolygonZkEVMBridgeV2.sol/PolygonZkEVMBridgeV2.json | jq -r '.abi' > ../bindings/ulxly/PolygonZkEVMBridgeV2.abi + cat ./out/PolygonZkEVMBridgeV2.sol/PolygonZkEVMBridgeV2.json | jq -r '.bytecode.object' > ../bindings/ulxly/PolygonZkEVMBridgeV2.bin + abigen --abi ../bindings/ulxly/PolygonZkEVMBridgeV2.abi --bin ../bindings/ulxly/PolygonZkEVMBridgeV2.bin --pkg ulxly --type ulxly --out ../bindings/ulxly/PolygonZkEVMBridgeV2.go + @echo "✅ ulxly/PolygonZkEVMBridgeV2.go generated" + .PHONY: gen-go-bindings gen-go-bindings: build gen-funder-go-bindings gen-tester-go-bindings gen-tokens-go-bindings ## Generate go bindings. From 01420402cc7c2a98ef95e0ee27ddaf929da2bae7 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Fri, 31 May 2024 19:43:51 -0400 Subject: [PATCH 02/46] feat: adding loop --- bindings/ulxly/PolygonZkEVMBridge.abi | 774 ++++++++++++ bindings/ulxly/PolygonZkEVMBridge.bin | 1 + bindings/ulxly/PolygonZkEVMBridge.go | 1666 +++++++++++++++++++++++++ cmd/ulxly/ulxly.go | 67 +- contracts/Makefile | 6 + 5 files changed, 2488 insertions(+), 26 deletions(-) create mode 100644 bindings/ulxly/PolygonZkEVMBridge.abi create mode 100644 bindings/ulxly/PolygonZkEVMBridge.bin create mode 100644 bindings/ulxly/PolygonZkEVMBridge.go diff --git a/bindings/ulxly/PolygonZkEVMBridge.abi b/bindings/ulxly/PolygonZkEVMBridge.abi new file mode 100644 index 00000000..345a3922 --- /dev/null +++ b/bindings/ulxly/PolygonZkEVMBridge.abi @@ -0,0 +1,774 @@ +[ + { + "type": "function", + "name": "activateEmergencyState", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "bridgeAsset", + "inputs": [ + { + "name": "destinationNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "destinationAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "forceUpdateGlobalExitRoot", + "type": "bool", + "internalType": "bool" + }, + { + "name": "permitData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "bridgeMessage", + "inputs": [ + { + "name": "destinationNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "destinationAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "forceUpdateGlobalExitRoot", + "type": "bool", + "internalType": "bool" + }, + { + "name": "metadata", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "claimAsset", + "inputs": [ + { + "name": "smtProof", + "type": "bytes32[32]", + "internalType": "bytes32[32]" + }, + { + "name": "index", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "mainnetExitRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "rollupExitRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "originNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originTokenAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "destinationNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "destinationAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "metadata", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimMessage", + "inputs": [ + { + "name": "smtProof", + "type": "bytes32[32]", + "internalType": "bytes32[32]" + }, + { + "name": "index", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "mainnetExitRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "rollupExitRoot", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "originNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "destinationNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "destinationAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "metadata", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "claimedBitMap", + "inputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "deactivateEmergencyState", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "depositCount", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getDepositRoot", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getLeafValue", + "inputs": [ + { + "name": "leafType", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "originNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "destinationNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "destinationAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "metadataHash", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "getTokenWrappedAddress", + "inputs": [ + { + "name": "originNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originTokenAddress", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "globalExitRootManager", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "contract IBasePolygonZkEVMGlobalExitRoot" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "_networkID", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "_globalExitRootManager", + "type": "address", + "internalType": "contract IBasePolygonZkEVMGlobalExitRoot" + }, + { + "name": "_polygonZkEVMaddress", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "isClaimed", + "inputs": [ + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isEmergencyState", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "lastUpdatedDepositCount", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint32", + "internalType": "uint32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "networkID", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint32", + "internalType": "uint32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "polygonZkEVMaddress", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "precalculatedWrapperAddress", + "inputs": [ + { + "name": "originNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originTokenAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "name", + "type": "string", + "internalType": "string" + }, + { + "name": "symbol", + "type": "string", + "internalType": "string" + }, + { + "name": "decimals", + "type": "uint8", + "internalType": "uint8" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "tokenInfoToWrappedToken", + "inputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "updateGlobalExitRoot", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "verifyMerkleProof", + "inputs": [ + { + "name": "leafHash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "smtProof", + "type": "bytes32[32]", + "internalType": "bytes32[32]" + }, + { + "name": "index", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "root", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "wrappedTokenToTokenInfo", + "inputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "originNetwork", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "originTokenAddress", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "event", + "name": "BridgeEvent", + "inputs": [ + { + "name": "leafType", + "type": "uint8", + "indexed": false, + "internalType": "uint8" + }, + { + "name": "originNetwork", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + }, + { + "name": "originAddress", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "destinationNetwork", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + }, + { + "name": "destinationAddress", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "metadata", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + }, + { + "name": "depositCount", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ClaimEvent", + "inputs": [ + { + "name": "index", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + }, + { + "name": "originNetwork", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + }, + { + "name": "originAddress", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "destinationAddress", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "EmergencyStateActivated", + "inputs": [], + "anonymous": false + }, + { + "type": "event", + "name": "EmergencyStateDeactivated", + "inputs": [], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint8", + "indexed": false, + "internalType": "uint8" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NewWrappedToken", + "inputs": [ + { + "name": "originNetwork", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + }, + { + "name": "originTokenAddress", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "wrappedTokenAddress", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "metadata", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AlreadyClaimed", + "inputs": [] + }, + { + "type": "error", + "name": "AmountDoesNotMatchMsgValue", + "inputs": [] + }, + { + "type": "error", + "name": "DestinationNetworkInvalid", + "inputs": [] + }, + { + "type": "error", + "name": "EtherTransferFailed", + "inputs": [] + }, + { + "type": "error", + "name": "GlobalExitRootInvalid", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidSmtProof", + "inputs": [] + }, + { + "type": "error", + "name": "MerkleTreeFull", + "inputs": [] + }, + { + "type": "error", + "name": "MessageFailed", + "inputs": [] + }, + { + "type": "error", + "name": "MsgValueNotZero", + "inputs": [] + }, + { + "type": "error", + "name": "NotValidAmount", + "inputs": [] + }, + { + "type": "error", + "name": "NotValidOwner", + "inputs": [] + }, + { + "type": "error", + "name": "NotValidSignature", + "inputs": [] + }, + { + "type": "error", + "name": "NotValidSpender", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyEmergencyState", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyNotEmergencyState", + "inputs": [] + }, + { + "type": "error", + "name": "OnlyPolygonZkEVM", + "inputs": [] + } +] diff --git a/bindings/ulxly/PolygonZkEVMBridge.bin b/bindings/ulxly/PolygonZkEVMBridge.bin new file mode 100644 index 00000000..f0b4afa0 --- /dev/null +++ b/bindings/ulxly/PolygonZkEVMBridge.bin @@ -0,0 +1 @@ +0x608060405234801561001057600080fd5b50614743806100206000396000f3fe6080604052600436106200015b5760003560e01c8063647c576c11620000c5578063be5831c71162000078578063be5831c7146200045a578063cd5865791462000480578063d02103ca1462000497578063dbc1697614620004c0578063ee25560b14620004d8578063fb570834146200050957600080fd5b8063647c576c146200033f57806379e2cf97146200036457806381b1c174146200037c5780639e34070f14620003b6578063aaa13cc214620003fb578063bab161bf146200042057600080fd5b80632d2c9d94116200011e5780632d2c9d9414620002255780632dfdf0b5146200024a578063318aee3d146200027157806334ac9cf214620002e05780633ae0504714620003025780633e197043146200031a57600080fd5b806315064c9614620001605780632072f6c5146200019157806322e95f2c14620001ab578063240ff37814620001e95780632cffd02e1462000200575b600080fd5b3480156200016d57600080fd5b506068546200017c9060ff1681565b60405190151581526020015b60405180910390f35b3480156200019e57600080fd5b50620001a96200052e565b005b348015620001b857600080fd5b50620001d0620001ca36600462002424565b62000566565b6040516001600160a01b03909116815260200162000188565b620001a9620001fa366004620024bb565b620005b9565b3480156200020d57600080fd5b50620001a96200021f36600462002552565b620006e0565b3480156200023257600080fd5b50620001a96200024436600462002552565b62000ae5565b3480156200025757600080fd5b506200026260535481565b60405190815260200162000188565b3480156200027e57600080fd5b50620002bb6200029036600462002638565b606b6020526000908152604090205463ffffffff81169064010000000090046001600160a01b031682565b6040805163ffffffff90931683526001600160a01b0390911660208301520162000188565b348015620002ed57600080fd5b50606c54620001d0906001600160a01b031681565b3480156200030f57600080fd5b506200026262000c34565b3480156200032757600080fd5b5062000262620003393660046200266f565b62000d1a565b3480156200034c57600080fd5b50620001a96200035e366004620026f9565b62000da7565b3480156200037157600080fd5b50620001a962000f24565b3480156200038957600080fd5b50620001d06200039b36600462002749565b606a602052600090815260409020546001600160a01b031681565b348015620003c357600080fd5b506200017c620003d536600462002749565b600881901c600090815260696020526040902054600160ff9092169190911b9081161490565b3480156200040857600080fd5b50620001d06200041a36600462002763565b62000f48565b3480156200042d57600080fd5b506068546200044490610100900463ffffffff1681565b60405163ffffffff909116815260200162000188565b3480156200046757600080fd5b506068546200044490600160c81b900463ffffffff1681565b620001a96200049136600462002817565b6200105f565b348015620004a457600080fd5b50606854620001d090600160281b90046001600160a01b031681565b348015620004cd57600080fd5b50620001a9620013f7565b348015620004e557600080fd5b5062000262620004f736600462002749565b60696020526000908152604090205481565b3480156200051657600080fd5b506200017c62000528366004620028b9565b6200142d565b606c546001600160a01b031633146200055a5760405163e2e8106b60e01b815260040160405180910390fd5b6200056462001516565b565b6000606a600084846040516020016200058192919062002906565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b031690505b92915050565b60685460ff1615620005de57604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff868116610100909204161480620006045750600263ffffffff861610155b1562000623576040516302caf51760e11b815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff16338888348888605354604051620006799998979695949392919062002959565b60405180910390a1620006c8620006c26001606860019054906101000a900463ffffffff16338989348989604051620006b4929190620029c8565b604051809103902062000d1a565b62001573565b8215620006d957620006d962001671565b5050505050565b60685460ff16156200070557604051630bc011ff60e21b815260040160405180910390fd5b6200071c8b8b8b8b8b8b8b8b8b8b8b600062001709565b6001600160a01b038616620007c557604080516000808252602082019092526001600160a01b03861690859060405162000757919062002a14565b60006040518083038185875af1925050503d806000811462000796576040519150601f19603f3d011682016040523d82523d6000602084013e6200079b565b606091505b5050905080620007be57604051630ce8f45160e31b815260040160405180910390fd5b5062000a97565b60685463ffffffff610100909104811690881603620007fa57620007f46001600160a01b038716858562001887565b62000a97565b600087876040516020016200081192919062002906565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b03168062000a2f57600080806200085a8688018862002aed565b9250925092506000858484846040516200087490620023e8565b620008829392919062002b91565b8190604051809103906000f5905080158015620008a3573d6000803e3d6000fd5b506040516340c10f1960e01b81526001600160a01b038c81166004830152602482018c9052919250908216906340c10f1990604401600060405180830381600087803b158015620008f357600080fd5b505af115801562000908573d6000803e3d6000fd5b5050505080606a600088815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060405180604001604052808e63ffffffff1681526020018d6001600160a01b0316815250606b6000836001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398d8d838b8b60405162000a1d95949392919062002bce565b60405180910390a15050505062000a94565b6040516340c10f1960e01b81526001600160a01b038781166004830152602482018790528216906340c10f1990604401600060405180830381600087803b15801562000a7a57600080fd5b505af115801562000a8f573d6000803e3d6000fd5b505050505b50505b7f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459838a8888878760405162000ad095949392919062002c09565b60405180910390a15050505050505050505050565b60685460ff161562000b0a57604051630bc011ff60e21b815260040160405180910390fd5b62000b218b8b8b8b8b8b8b8b8b8b8b600162001709565b6000846001600160a01b031684888a868660405160240162000b47949392919062002c40565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b1790525162000b7e919062002a14565b60006040518083038185875af1925050503d806000811462000bbd576040519150601f19603f3d011682016040523d82523d6000602084013e62000bc2565b606091505b505090508062000be5576040516337e391c360e01b815260040160405180910390fd5b7f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459838b8989888860405162000c1e95949392919062002c09565b60405180910390a1505050505050505050505050565b605354600090819081805b602081101562000d11578083901c60011660010362000ca2576033816020811062000c6e5762000c6e62002c7d565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935062000ccf565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b6040805160208101849052908101839052606001604051602081830303815290604052805190602001209150808062000d089062002ca9565b91505062000c3f565b50919392505050565b6040516001600160f81b031960f889901b1660208201526001600160e01b031960e088811b821660218401526001600160601b0319606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b600054610100900460ff161580801562000dc85750600054600160ff909116105b8062000de45750303b15801562000de4575060005460ff166001145b62000e4d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000e71576000805461ff0019166101001790555b60688054610100600160c81b03191661010063ffffffff87160265010000000000600160c81b03191617600160281b6001600160a01b038681169190910291909117909155606c80546001600160a01b03191691841691909117905562000ed7620018ec565b801562000f1e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b605354606854600160c81b900463ffffffff16101562000564576200056462001671565b600080888860405160200162000f6092919062002906565b604051602081830303815290604052805190602001209050600060ff60f81b30836040518060200162000f9390620023e8565b601f1982820381018352601f90910116604081905262000fc0908d908d908d908d908d9060200162002cc5565b60408051601f198184030181529082905262000fe0929160200162002d06565b604051602081830303815290604052805190602001206040516020016200103994939291906001600160f81b031994909416845260609290921b6001600160601b03191660018401526015830152603582015260550190565b60408051808303601f1901815291905280516020909101209a9950505050505050505050565b60685460ff16156200108457604051630bc011ff60e21b815260040160405180910390fd5b6200108e62001920565b60685463ffffffff888116610100909204161480620010b45750600263ffffffff881610155b15620010d3576040516302caf51760e11b815260040160405180910390fd5b6000806060876001600160a01b0388166200111357883414620011095760405163b89240f560e01b815260040160405180910390fd5b6000925062001368565b3415620011335760405163798ee6f160e01b815260040160405180910390fd5b6001600160a01b038089166000908152606b602090815260409182902082518084019093525463ffffffff8116835264010000000090049092169181018290529015620011f057604051632770a7eb60e21b8152336004820152602481018b90526001600160a01b038a1690639dc29fac90604401600060405180830381600087803b158015620011c357600080fd5b505af1158015620011d8573d6000803e3d6000fd5b50505050806020015194508060000151935062001366565b8515620012055762001205898b89896200197b565b6040516370a0823160e01b81523060048201526000906001600160a01b038b16906370a0823190602401602060405180830381865afa1580156200124d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001273919062002d39565b90506200128c6001600160a01b038b1633308e62001cdd565b6040516370a0823160e01b81523060048201526000906001600160a01b038c16906370a0823190602401602060405180830381865afa158015620012d4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620012fa919062002d39565b905062001308828262002d53565b6068548c9850610100900463ffffffff1696509350620013288762001d17565b620013338c62001dde565b6200133e8d62001e9c565b604051602001620013529392919062002b91565b604051602081830303815290604052945050505b505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b600084868e8e8688605354604051620013aa98979695949392919062002d69565b60405180910390a1620013cf620006c2600085878f8f87898051906020012062000d1a565b8615620013e057620013e062001671565b50505050620013ee60018055565b50505050505050565b606c546001600160a01b03163314620014235760405163e2e8106b60e01b815260040160405180910390fd5b6200056462001f63565b600084815b60208110156200150857600163ffffffff8616821c81169003620014a45785816020811062001465576200146562002c7d565b60200201358260405160200162001486929190918252602082015260400190565b604051602081830303815290604052805190602001209150620014f3565b81868260208110620014ba57620014ba62002c7d565b6020020135604051602001620014da929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b80620014ff8162002ca9565b91505062001432565b50821490505b949350505050565b60685460ff16156200153b57604051630bc011ff60e21b815260040160405180910390fd5b6068805460ff191660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a549790600090a1565b806001620015846020600262002ed3565b62001590919062002d53565b60535410620015b2576040516377ae67b360e11b815260040160405180910390fd5b6000605360008154620015c59062002ca9565b9182905550905060005b602081101562001661578082901c60011660010362001607578260338260208110620015ff57620015ff62002c7d565b015550505050565b603381602081106200161d576200161d62002c7d565b015460408051602081019290925281018490526060016040516020818303038152906040528051906020012092508080620016589062002ca9565b915050620015cf565b506200166c62002ee1565b505050565b6053546068805463ffffffff909216600160c81b0263ffffffff60c81b1990921691909117908190556001600160a01b03600160281b909104166333d6247d620016ba62000c34565b6040518263ffffffff1660e01b8152600401620016d991815260200190565b600060405180830381600087803b158015620016f457600080fd5b505af115801562000f1e573d6000803e3d6000fd5b6200171a8b63ffffffff1662001fbc565b6068546040805160208082018e90528183018d9052825180830384018152606083019384905280519101206312bd9b1960e11b9092526064810191909152600091600160281b90046001600160a01b03169063257b3632906084016020604051808303816000875af115801562001795573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017bb919062002d39565b905080600003620017de57604051622f6fad60e01b815260040160405180910390fd5b60685463ffffffff88811661010090920416146200180f576040516302caf51760e11b815260040160405180910390fd5b606854600090610100900463ffffffff166200182d57508962001830565b508a5b6200185962001850848c8c8c8c8c8c8c604051620006b4929190620029c8565b8f8f846200142d565b62001877576040516338105f3b60e21b815260040160405180910390fd5b5050505050505050505050505050565b6040516001600160a01b0383166024820152604481018290526200166c90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915262002008565b600054610100900460ff16620019165760405162461bcd60e51b815260040162000e449062002ef7565b62000564620020e1565b600260015403620019745760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162000e44565b6002600155565b60006200198c600482848662002f42565b620019979162002f6e565b9050632afa533160e01b6001600160e01b031982160162001b38576000808080808080620019c9896004818d62002f42565b810190620019d8919062002f9f565b9650965096509650965096509650336001600160a01b0316876001600160a01b03161462001a195760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b038616301462001a435760405163750643af60e01b815260040160405180910390fd5b8a851462001a64576040516303fffc4b60e01b815260040160405180910390fd5b604080516001600160a01b0389811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180516001600160e01b031663d505accf60e01b1790529151918e169162001ae4919062002a14565b6000604051808303816000865af19150503d806000811462001b23576040519150601f19603f3d011682016040523d82523d6000602084013e62001b28565b606091505b50505050505050505050620006d9565b6001600160e01b031981166323f2ebc360e21b1462001b6a57604051637141605d60e11b815260040160405180910390fd5b60008080808080808062001b828a6004818e62002f42565b81019062001b91919062002ffa565b97509750975097509750975097509750336001600160a01b0316886001600160a01b03161462001bd45760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b038716301462001bfe5760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b038a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180516001600160e01b03166323f2ebc360e21b1790529151918f169162001c87919062002a14565b6000604051808303816000865af19150503d806000811462001cc6576040519150601f19603f3d011682016040523d82523d6000602084013e62001ccb565b606091505b50505050505050505050505050505050565b6040516001600160a01b038085166024830152831660448201526064810182905262000f1e9085906323b872dd60e01b90608401620018b4565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b179052905160609160009182916001600160a01b0386169162001d60919062002a14565b600060405180830381855afa9150503d806000811462001d9d576040519150601f19603f3d011682016040523d82523d6000602084013e62001da2565b606091505b50915091508162001dd357604051806040016040528060078152602001664e4f5f4e414d4560c81b8152506200150e565b6200150e816200210b565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b179052905160609160009182916001600160a01b0386169162001e27919062002a14565b600060405180830381855afa9150503d806000811462001e64576040519150601f19603f3d011682016040523d82523d6000602084013e62001e69565b606091505b50915091508162001dd357604051806040016040528060098152602001681393d7d4d6535093d360ba1b8152506200150e565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b0386169162001ee4919062002a14565b600060405180830381855afa9150503d806000811462001f21576040519150601f19603f3d011682016040523d82523d6000602084013e62001f26565b606091505b509150915081801562001f3a575080516020145b62001f475760126200150e565b808060200190518101906200150e919062003086565b60018055565b60685460ff1662001f8757604051635386698160e01b815260040160405180910390fd5b6068805460ff191690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b390600090a1565b600881901c60008181526069602052604081208054600160ff861690811b91821892839055929091908183169003620006d957604051630c8d9eab60e31b815260040160405180910390fd5b60006200205f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620022b59092919063ffffffff16565b8051909150156200166c5780806020019051810190620020809190620030a6565b6200166c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000e44565b600054610100900460ff1662001f5d5760405162461bcd60e51b815260040162000e449062002ef7565b606060408251106200212d5781806020019051810190620005b39190620030c6565b8151602003620022825760005b6020811080156200216d57508281815181106200215b576200215b62002c7d565b01602001516001600160f81b03191615155b156200218857806200217f8162002ca9565b9150506200213a565b80600003620021c15750506040805180820190915260128152714e4f545f56414c49445f454e434f44494e4760701b6020820152919050565b60008167ffffffffffffffff811115620021df57620021df620029d8565b6040519080825280601f01601f1916602001820160405280156200220a576020820181803683370190505b50905060005b828110156200227a578481815181106200222e576200222e62002c7d565b602001015160f81c60f81b8282815181106200224e576200224e62002c7d565b60200101906001600160f81b031916908160001a90535080620022718162002ca9565b91505062002210565b509392505050565b50506040805180820190915260128152714e4f545f56414c49445f454e434f44494e4760701b602082015290565b919050565b60606200150e848460008585600080866001600160a01b03168587604051620022df919062002a14565b60006040518083038185875af1925050503d80600081146200231e576040519150601f19603f3d011682016040523d82523d6000602084013e62002323565b606091505b5091509150620023368783838762002341565b979650505050505050565b60608315620023b5578251600003620023ad576001600160a01b0385163b620023ad5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000e44565b50816200150e565b6200150e8383815115620023cc5781518083602001fd5b8060405162461bcd60e51b815260040162000e44919062003146565b6115b2806200315c83390190565b803563ffffffff81168114620022b057600080fd5b6001600160a01b03811681146200242157600080fd5b50565b600080604083850312156200243857600080fd5b6200244383620023f6565b9150602083013562002455816200240b565b809150509250929050565b80151581146200242157600080fd5b60008083601f8401126200248257600080fd5b50813567ffffffffffffffff8111156200249b57600080fd5b602083019150836020828501011115620024b457600080fd5b9250929050565b600080600080600060808688031215620024d457600080fd5b620024df86620023f6565b94506020860135620024f1816200240b565b93506040860135620025038162002460565b9250606086013567ffffffffffffffff8111156200252057600080fd5b6200252e888289016200246f565b969995985093965092949392505050565b806104008101831015620005b357600080fd5b60008060008060008060008060008060006105208c8e0312156200257557600080fd5b620025818d8d6200253f565b9a50620025926104008d01620023f6565b99506104208c013598506104408c01359750620025b36104608d01620023f6565b96506104808c0135620025c6816200240b565b9550620025d76104a08d01620023f6565b94506104c08c0135620025ea816200240b565b93506104e08c013592506105008c013567ffffffffffffffff8111156200261057600080fd5b6200261e8e828f016200246f565b915080935050809150509295989b509295989b9093969950565b6000602082840312156200264b57600080fd5b813562002658816200240b565b9392505050565b60ff811681146200242157600080fd5b600080600080600080600060e0888a0312156200268b57600080fd5b873562002698816200265f565b9650620026a860208901620023f6565b95506040880135620026ba816200240b565b9450620026ca60608901620023f6565b93506080880135620026dc816200240b565b9699959850939692959460a0840135945060c09093013592915050565b6000806000606084860312156200270f57600080fd5b6200271a84620023f6565b925060208401356200272c816200240b565b915060408401356200273e816200240b565b809150509250925092565b6000602082840312156200275c57600080fd5b5035919050565b600080600080600080600060a0888a0312156200277f57600080fd5b6200278a88620023f6565b965060208801356200279c816200240b565b9550604088013567ffffffffffffffff80821115620027ba57600080fd5b620027c88b838c016200246f565b909750955060608a0135915080821115620027e257600080fd5b50620027f18a828b016200246f565b909450925050608088013562002807816200265f565b8091505092959891949750929550565b600080600080600080600060c0888a0312156200283357600080fd5b6200283e88620023f6565b9650602088013562002850816200240b565b955060408801359450606088013562002869816200240b565b935060808801356200287b8162002460565b925060a088013567ffffffffffffffff8111156200289857600080fd5b620028a68a828b016200246f565b989b979a50959850939692959293505050565b6000806000806104608587031215620028d157600080fd5b84359350620028e486602087016200253f565b9250620028f56104208601620023f6565b939692955092936104400135925050565b60e09290921b6001600160e01b031916825260601b6001600160601b031916600482015260180190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60ff8a16815263ffffffff89811660208301526001600160a01b03898116604084015288821660608401528716608083015260a0820186905261010060c08301819052600091620029ae848301878962002930565b925080851660e085015250509a9950505050505050505050565b8183823760009101908152919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562002a0b578181015183820152602001620029f1565b50506000910152565b6000825162002a28818460208701620029ee565b9190910192915050565b604051601f8201601f1916810167ffffffffffffffff8111828210171562002a5e5762002a5e620029d8565b604052919050565b600067ffffffffffffffff82111562002a835762002a83620029d8565b50601f01601f191660200190565b600082601f83011262002aa357600080fd5b813562002aba62002ab48262002a66565b62002a32565b81815284602083860101111562002ad057600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121562002b0357600080fd5b833567ffffffffffffffff8082111562002b1c57600080fd5b62002b2a8783880162002a91565b9450602086013591508082111562002b4157600080fd5b5062002b508682870162002a91565b92505060408401356200273e816200265f565b6000815180845262002b7d816020860160208601620029ee565b601f01601f19169290920160200192915050565b60608152600062002ba6606083018662002b63565b828103602084015262002bba818662002b63565b91505060ff83166040830152949350505050565b63ffffffff861681526001600160a01b0385811660208301528416604082015260806060820181905260009062002336908301848662002930565b63ffffffff95861681529390941660208401526001600160a01b039182166040840152166060820152608081019190915260a00190565b6001600160a01b038516815263ffffffff8416602082015260606040820181905260009062002c73908301848662002930565b9695505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820162002cbe5762002cbe62002c93565b5060010190565b60608152600062002cdb60608301878962002930565b828103602084015262002cf081868862002930565b91505060ff831660408301529695505050505050565b6000835162002d1a818460208801620029ee565b83519083019062002d30818360208801620029ee565b01949350505050565b60006020828403121562002d4c57600080fd5b5051919050565b81810381811115620005b357620005b362002c93565b60ff8916815263ffffffff88811660208301526001600160a01b03888116604084015287821660608401528616608083015260a0820185905261010060c0830181905260009162002dbd8483018762002b63565b925080851660e085015250509998505050505050505050565b600181815b8085111562002e1757816000190482111562002dfb5762002dfb62002c93565b8085161562002e0957918102915b93841c939080029062002ddb565b509250929050565b60008262002e3057506001620005b3565b8162002e3f57506000620005b3565b816001811462002e58576002811462002e635762002e83565b6001915050620005b3565b60ff84111562002e775762002e7762002c93565b50506001821b620005b3565b5060208310610133831016604e8410600b841016171562002ea8575081810a620005b3565b62002eb4838362002dd6565b806000190482111562002ecb5762002ecb62002c93565b029392505050565b600062002658838362002e1f565b634e487b7160e01b600052600160045260246000fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6000808585111562002f5357600080fd5b8386111562002f6157600080fd5b5050820193919092039150565b6001600160e01b0319813581811691600485101562002f975780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a03121562002fbb57600080fd5b873562002fc8816200240b565b9650602088013562002fda816200240b565b955060408801359450606088013593506080880135620026dc816200265f565b600080600080600080600080610100898b0312156200301857600080fd5b883562003025816200240b565b9750602089013562003037816200240b565b965060408901359550606089013594506080890135620030578162002460565b935060a089013562003069816200265f565b979a969950949793969295929450505060c08201359160e0013590565b6000602082840312156200309957600080fd5b815162002658816200265f565b600060208284031215620030b957600080fd5b8151620026588162002460565b600060208284031215620030d957600080fd5b815167ffffffffffffffff811115620030f157600080fd5b8201601f810184136200310357600080fd5b80516200311462002ab48262002a66565b8181528560208385010111156200312a57600080fd5b6200313d826020830160208601620029ee565b95945050505050565b60208152600062002658602083018462002b6356fe6101006040523480156200001257600080fd5b50604051620015b2380380620015b283398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516110f6620004bc60003960006101f70152600081816102ba015281816104e0015261054e0152600061049101526000818161031f015261045b01526110f66000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806370a08231116100b8578063a457c2d71161007c578063a457c2d7146102f4578063a9059cbb14610307578063cd0d00961461031a578063d505accf14610341578063dd62ed3e14610354578063ffa1ad741461036757600080fd5b806370a08231146102515780637ecebe001461027a57806395d89b411461029a5780639dc29fac146102a2578063a3c573eb146102b557600080fd5b806330adf81f116100ff57806330adf81f146101c9578063313ce567146101f05780633644e51514610221578063395093511461022957806340c10f191461023c57600080fd5b806306fdde031461013c578063095ea7b31461015a57806318160ddd1461017d57806320606b701461018f57806323b872dd146101b6575b600080fd5b610144610387565b6040516101519190610e5c565b60405180910390f35b61016d610168366004610ec6565b610419565b6040519015158152602001610151565b6002545b604051908152602001610151565b6101817f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b61016d6101c4366004610ef0565b610433565b6101817f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610151565b610181610457565b61016d610237366004610ec6565b6104b3565b61024f61024a366004610ec6565b6104d5565b005b61018161025f366004610f2c565b6001600160a01b031660009081526020819052604090205490565b610181610288366004610f2c565b60056020526000908152604090205481565b610144610534565b61024f6102b0366004610ec6565b610543565b6102dc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610151565b61016d610302366004610ec6565b610595565b61016d610315366004610ec6565b610610565b6101817f000000000000000000000000000000000000000000000000000000000000000081565b61024f61034f366004610f4e565b61061e565b610181610362366004610fc1565b610859565b610144604051806040016040528060018152602001603160f81b81525081565b60606003805461039690610ff4565b80601f01602080910402602001604051908101604052809291908181526020018280546103c290610ff4565b801561040f5780601f106103e45761010080835404028352916020019161040f565b820191906000526020600020905b8154815290600101906020018083116103f257829003601f168201915b5050505050905090565b600033610427818585610884565b60019150505b92915050565b6000336104418582856109a9565b61044c858585610a23565b506001949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000461461048e5761048946610bc7565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b6000336104278185856104c68383610859565b6104d09190611044565b610884565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105265760405162461bcd60e51b815260040161051d90611057565b60405180910390fd5b6105308282610c73565b5050565b60606004805461039690610ff4565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461058b5760405162461bcd60e51b815260040161051d90611057565b6105308282610d32565b600033816105a38286610859565b9050838110156106035760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161051d565b61044c8286868403610884565b600033610427818585610a23565b8342111561067a5760405162461bcd60e51b8152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a20457870697265642070656044820152631c9b5a5d60e21b606482015260840161051d565b6001600160a01b038716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866106c7836110a7565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610725610457565b60405161190160f01b602082015260228101919091526042810183905260620160408051601f198184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa1580156107b0573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906107e65750896001600160a01b0316816001600160a01b0316145b6108425760405162461bcd60e51b815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c6964207369604482015266676e617475726560c81b606482015260840161051d565b61084d8a8a8a610884565b50505050505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b0383166108e65760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161051d565b6001600160a01b0382166109475760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161051d565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006109b58484610859565b90506000198114610a1d5781811015610a105760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161051d565b610a1d8484848403610884565b50505050565b6001600160a01b038316610a875760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161051d565b6001600160a01b038216610ae95760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161051d565b6001600160a01b03831660009081526020819052604090205481811015610b615760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161051d565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610a1d565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f610bf2610387565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6001600160a01b038216610cc95760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161051d565b8060026000828254610cdb9190611044565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b038216610d925760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161051d565b6001600160a01b03821660009081526020819052604090205481811015610e065760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161051d565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910161099c565b600060208083528351808285015260005b81811015610e8957858101830151858201604001528201610e6d565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610ec157600080fd5b919050565b60008060408385031215610ed957600080fd5b610ee283610eaa565b946020939093013593505050565b600080600060608486031215610f0557600080fd5b610f0e84610eaa565b9250610f1c60208501610eaa565b9150604084013590509250925092565b600060208284031215610f3e57600080fd5b610f4782610eaa565b9392505050565b600080600080600080600060e0888a031215610f6957600080fd5b610f7288610eaa565b9650610f8060208901610eaa565b95506040880135945060608801359350608088013560ff81168114610fa457600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215610fd457600080fd5b610fdd83610eaa565b9150610feb60208401610eaa565b90509250929050565b600181811c9082168061100857607f821691505b60208210810361102857634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561042d5761042d61102e565b60208082526030908201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60408201526f6c79676f6e5a6b45564d42726964676560801b606082015260800190565b6000600182016110b9576110b961102e565b506001019056fea2646970667358221220e578d8e4b71a5c98739e7f11de9b62b5bff7c0ec9d1c2013a5019efa3df3a96d64736f6c63430008140033a2646970667358221220a5db4ca599c25af724716ede251c43e562514e0970d03b930b42a70d351d54b164736f6c63430008140033 diff --git a/bindings/ulxly/PolygonZkEVMBridge.go b/bindings/ulxly/PolygonZkEVMBridge.go new file mode 100644 index 00000000..fee5c11b --- /dev/null +++ b/bindings/ulxly/PolygonZkEVMBridge.go @@ -0,0 +1,1666 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package ulxly + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// LegacyMetaData contains all meta data concerning the Legacy contract. +var LegacyMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"activateEmergencyState\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"bridgeAsset\",\"inputs\":[{\"name\":\"destinationNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"forceUpdateGlobalExitRoot\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"permitData\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"bridgeMessage\",\"inputs\":[{\"name\":\"destinationNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"forceUpdateGlobalExitRoot\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"metadata\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"claimAsset\",\"inputs\":[{\"name\":\"smtProof\",\"type\":\"bytes32[32]\",\"internalType\":\"bytes32[32]\"},{\"name\":\"index\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"mainnetExitRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"rollupExitRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"originNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"originTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"metadata\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"claimMessage\",\"inputs\":[{\"name\":\"smtProof\",\"type\":\"bytes32[32]\",\"internalType\":\"bytes32[32]\"},{\"name\":\"index\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"mainnetExitRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"rollupExitRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"originNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"originAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"metadata\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"claimedBitMap\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deactivateEmergencyState\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"depositCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getDepositRoot\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getLeafValue\",\"inputs\":[{\"name\":\"leafType\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"originNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"originAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"metadataHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"getTokenWrappedAddress\",\"inputs\":[{\"name\":\"originNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"originTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"globalExitRootManager\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBasePolygonZkEVMGlobalExitRoot\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_networkID\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_globalExitRootManager\",\"type\":\"address\",\"internalType\":\"contractIBasePolygonZkEVMGlobalExitRoot\"},{\"name\":\"_polygonZkEVMaddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isClaimed\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isEmergencyState\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"lastUpdatedDepositCount\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"networkID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"polygonZkEVMaddress\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"precalculatedWrapperAddress\",\"inputs\":[{\"name\":\"originNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"originTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"name\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"symbol\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"decimals\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"tokenInfoToWrappedToken\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"updateGlobalExitRoot\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifyMerkleProof\",\"inputs\":[{\"name\":\"leafHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"smtProof\",\"type\":\"bytes32[32]\",\"internalType\":\"bytes32[32]\"},{\"name\":\"index\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"wrappedTokenToTokenInfo\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"originNetwork\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"originTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"BridgeEvent\",\"inputs\":[{\"name\":\"leafType\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"},{\"name\":\"originNetwork\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"},{\"name\":\"originAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"destinationNetwork\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"metadata\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"},{\"name\":\"depositCount\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ClaimEvent\",\"inputs\":[{\"name\":\"index\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"},{\"name\":\"originNetwork\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"},{\"name\":\"originAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"EmergencyStateActivated\",\"inputs\":[],\"anonymous\":false},{\"type\":\"event\",\"name\":\"EmergencyStateDeactivated\",\"inputs\":[],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"NewWrappedToken\",\"inputs\":[{\"name\":\"originNetwork\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"},{\"name\":\"originTokenAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"wrappedTokenAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"metadata\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AlreadyClaimed\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"AmountDoesNotMatchMsgValue\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"DestinationNetworkInvalid\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"EtherTransferFailed\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"GlobalExitRootInvalid\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSmtProof\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MerkleTreeFull\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MessageFailed\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MsgValueNotZero\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotValidAmount\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotValidOwner\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotValidSignature\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotValidSpender\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyEmergencyState\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyNotEmergencyState\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OnlyPolygonZkEVM\",\"inputs\":[]}]", + Bin: "0x608060405234801561001057600080fd5b50614743806100206000396000f3fe6080604052600436106200015b5760003560e01c8063647c576c11620000c5578063be5831c71162000078578063be5831c7146200045a578063cd5865791462000480578063d02103ca1462000497578063dbc1697614620004c0578063ee25560b14620004d8578063fb570834146200050957600080fd5b8063647c576c146200033f57806379e2cf97146200036457806381b1c174146200037c5780639e34070f14620003b6578063aaa13cc214620003fb578063bab161bf146200042057600080fd5b80632d2c9d94116200011e5780632d2c9d9414620002255780632dfdf0b5146200024a578063318aee3d146200027157806334ac9cf214620002e05780633ae0504714620003025780633e197043146200031a57600080fd5b806315064c9614620001605780632072f6c5146200019157806322e95f2c14620001ab578063240ff37814620001e95780632cffd02e1462000200575b600080fd5b3480156200016d57600080fd5b506068546200017c9060ff1681565b60405190151581526020015b60405180910390f35b3480156200019e57600080fd5b50620001a96200052e565b005b348015620001b857600080fd5b50620001d0620001ca36600462002424565b62000566565b6040516001600160a01b03909116815260200162000188565b620001a9620001fa366004620024bb565b620005b9565b3480156200020d57600080fd5b50620001a96200021f36600462002552565b620006e0565b3480156200023257600080fd5b50620001a96200024436600462002552565b62000ae5565b3480156200025757600080fd5b506200026260535481565b60405190815260200162000188565b3480156200027e57600080fd5b50620002bb6200029036600462002638565b606b6020526000908152604090205463ffffffff81169064010000000090046001600160a01b031682565b6040805163ffffffff90931683526001600160a01b0390911660208301520162000188565b348015620002ed57600080fd5b50606c54620001d0906001600160a01b031681565b3480156200030f57600080fd5b506200026262000c34565b3480156200032757600080fd5b5062000262620003393660046200266f565b62000d1a565b3480156200034c57600080fd5b50620001a96200035e366004620026f9565b62000da7565b3480156200037157600080fd5b50620001a962000f24565b3480156200038957600080fd5b50620001d06200039b36600462002749565b606a602052600090815260409020546001600160a01b031681565b348015620003c357600080fd5b506200017c620003d536600462002749565b600881901c600090815260696020526040902054600160ff9092169190911b9081161490565b3480156200040857600080fd5b50620001d06200041a36600462002763565b62000f48565b3480156200042d57600080fd5b506068546200044490610100900463ffffffff1681565b60405163ffffffff909116815260200162000188565b3480156200046757600080fd5b506068546200044490600160c81b900463ffffffff1681565b620001a96200049136600462002817565b6200105f565b348015620004a457600080fd5b50606854620001d090600160281b90046001600160a01b031681565b348015620004cd57600080fd5b50620001a9620013f7565b348015620004e557600080fd5b5062000262620004f736600462002749565b60696020526000908152604090205481565b3480156200051657600080fd5b506200017c62000528366004620028b9565b6200142d565b606c546001600160a01b031633146200055a5760405163e2e8106b60e01b815260040160405180910390fd5b6200056462001516565b565b6000606a600084846040516020016200058192919062002906565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b031690505b92915050565b60685460ff1615620005de57604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff868116610100909204161480620006045750600263ffffffff861610155b1562000623576040516302caf51760e11b815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff16338888348888605354604051620006799998979695949392919062002959565b60405180910390a1620006c8620006c26001606860019054906101000a900463ffffffff16338989348989604051620006b4929190620029c8565b604051809103902062000d1a565b62001573565b8215620006d957620006d962001671565b5050505050565b60685460ff16156200070557604051630bc011ff60e21b815260040160405180910390fd5b6200071c8b8b8b8b8b8b8b8b8b8b8b600062001709565b6001600160a01b038616620007c557604080516000808252602082019092526001600160a01b03861690859060405162000757919062002a14565b60006040518083038185875af1925050503d806000811462000796576040519150601f19603f3d011682016040523d82523d6000602084013e6200079b565b606091505b5050905080620007be57604051630ce8f45160e31b815260040160405180910390fd5b5062000a97565b60685463ffffffff610100909104811690881603620007fa57620007f46001600160a01b038716858562001887565b62000a97565b600087876040516020016200081192919062002906565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b03168062000a2f57600080806200085a8688018862002aed565b9250925092506000858484846040516200087490620023e8565b620008829392919062002b91565b8190604051809103906000f5905080158015620008a3573d6000803e3d6000fd5b506040516340c10f1960e01b81526001600160a01b038c81166004830152602482018c9052919250908216906340c10f1990604401600060405180830381600087803b158015620008f357600080fd5b505af115801562000908573d6000803e3d6000fd5b5050505080606a600088815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060405180604001604052808e63ffffffff1681526020018d6001600160a01b0316815250606b6000836001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398d8d838b8b60405162000a1d95949392919062002bce565b60405180910390a15050505062000a94565b6040516340c10f1960e01b81526001600160a01b038781166004830152602482018790528216906340c10f1990604401600060405180830381600087803b15801562000a7a57600080fd5b505af115801562000a8f573d6000803e3d6000fd5b505050505b50505b7f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459838a8888878760405162000ad095949392919062002c09565b60405180910390a15050505050505050505050565b60685460ff161562000b0a57604051630bc011ff60e21b815260040160405180910390fd5b62000b218b8b8b8b8b8b8b8b8b8b8b600162001709565b6000846001600160a01b031684888a868660405160240162000b47949392919062002c40565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b1790525162000b7e919062002a14565b60006040518083038185875af1925050503d806000811462000bbd576040519150601f19603f3d011682016040523d82523d6000602084013e62000bc2565b606091505b505090508062000be5576040516337e391c360e01b815260040160405180910390fd5b7f25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe275459838b8989888860405162000c1e95949392919062002c09565b60405180910390a1505050505050505050505050565b605354600090819081805b602081101562000d11578083901c60011660010362000ca2576033816020811062000c6e5762000c6e62002c7d565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935062000ccf565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b6040805160208101849052908101839052606001604051602081830303815290604052805190602001209150808062000d089062002ca9565b91505062000c3f565b50919392505050565b6040516001600160f81b031960f889901b1660208201526001600160e01b031960e088811b821660218401526001600160601b0319606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b600054610100900460ff161580801562000dc85750600054600160ff909116105b8062000de45750303b15801562000de4575060005460ff166001145b62000e4d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000e71576000805461ff0019166101001790555b60688054610100600160c81b03191661010063ffffffff87160265010000000000600160c81b03191617600160281b6001600160a01b038681169190910291909117909155606c80546001600160a01b03191691841691909117905562000ed7620018ec565b801562000f1e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b605354606854600160c81b900463ffffffff16101562000564576200056462001671565b600080888860405160200162000f6092919062002906565b604051602081830303815290604052805190602001209050600060ff60f81b30836040518060200162000f9390620023e8565b601f1982820381018352601f90910116604081905262000fc0908d908d908d908d908d9060200162002cc5565b60408051601f198184030181529082905262000fe0929160200162002d06565b604051602081830303815290604052805190602001206040516020016200103994939291906001600160f81b031994909416845260609290921b6001600160601b03191660018401526015830152603582015260550190565b60408051808303601f1901815291905280516020909101209a9950505050505050505050565b60685460ff16156200108457604051630bc011ff60e21b815260040160405180910390fd5b6200108e62001920565b60685463ffffffff888116610100909204161480620010b45750600263ffffffff881610155b15620010d3576040516302caf51760e11b815260040160405180910390fd5b6000806060876001600160a01b0388166200111357883414620011095760405163b89240f560e01b815260040160405180910390fd5b6000925062001368565b3415620011335760405163798ee6f160e01b815260040160405180910390fd5b6001600160a01b038089166000908152606b602090815260409182902082518084019093525463ffffffff8116835264010000000090049092169181018290529015620011f057604051632770a7eb60e21b8152336004820152602481018b90526001600160a01b038a1690639dc29fac90604401600060405180830381600087803b158015620011c357600080fd5b505af1158015620011d8573d6000803e3d6000fd5b50505050806020015194508060000151935062001366565b8515620012055762001205898b89896200197b565b6040516370a0823160e01b81523060048201526000906001600160a01b038b16906370a0823190602401602060405180830381865afa1580156200124d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001273919062002d39565b90506200128c6001600160a01b038b1633308e62001cdd565b6040516370a0823160e01b81523060048201526000906001600160a01b038c16906370a0823190602401602060405180830381865afa158015620012d4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620012fa919062002d39565b905062001308828262002d53565b6068548c9850610100900463ffffffff1696509350620013288762001d17565b620013338c62001dde565b6200133e8d62001e9c565b604051602001620013529392919062002b91565b604051602081830303815290604052945050505b505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b600084868e8e8688605354604051620013aa98979695949392919062002d69565b60405180910390a1620013cf620006c2600085878f8f87898051906020012062000d1a565b8615620013e057620013e062001671565b50505050620013ee60018055565b50505050505050565b606c546001600160a01b03163314620014235760405163e2e8106b60e01b815260040160405180910390fd5b6200056462001f63565b600084815b60208110156200150857600163ffffffff8616821c81169003620014a45785816020811062001465576200146562002c7d565b60200201358260405160200162001486929190918252602082015260400190565b604051602081830303815290604052805190602001209150620014f3565b81868260208110620014ba57620014ba62002c7d565b6020020135604051602001620014da929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b80620014ff8162002ca9565b91505062001432565b50821490505b949350505050565b60685460ff16156200153b57604051630bc011ff60e21b815260040160405180910390fd5b6068805460ff191660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a549790600090a1565b806001620015846020600262002ed3565b62001590919062002d53565b60535410620015b2576040516377ae67b360e11b815260040160405180910390fd5b6000605360008154620015c59062002ca9565b9182905550905060005b602081101562001661578082901c60011660010362001607578260338260208110620015ff57620015ff62002c7d565b015550505050565b603381602081106200161d576200161d62002c7d565b015460408051602081019290925281018490526060016040516020818303038152906040528051906020012092508080620016589062002ca9565b915050620015cf565b506200166c62002ee1565b505050565b6053546068805463ffffffff909216600160c81b0263ffffffff60c81b1990921691909117908190556001600160a01b03600160281b909104166333d6247d620016ba62000c34565b6040518263ffffffff1660e01b8152600401620016d991815260200190565b600060405180830381600087803b158015620016f457600080fd5b505af115801562000f1e573d6000803e3d6000fd5b6200171a8b63ffffffff1662001fbc565b6068546040805160208082018e90528183018d9052825180830384018152606083019384905280519101206312bd9b1960e11b9092526064810191909152600091600160281b90046001600160a01b03169063257b3632906084016020604051808303816000875af115801562001795573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017bb919062002d39565b905080600003620017de57604051622f6fad60e01b815260040160405180910390fd5b60685463ffffffff88811661010090920416146200180f576040516302caf51760e11b815260040160405180910390fd5b606854600090610100900463ffffffff166200182d57508962001830565b508a5b6200185962001850848c8c8c8c8c8c8c604051620006b4929190620029c8565b8f8f846200142d565b62001877576040516338105f3b60e21b815260040160405180910390fd5b5050505050505050505050505050565b6040516001600160a01b0383166024820152604481018290526200166c90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915262002008565b600054610100900460ff16620019165760405162461bcd60e51b815260040162000e449062002ef7565b62000564620020e1565b600260015403620019745760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162000e44565b6002600155565b60006200198c600482848662002f42565b620019979162002f6e565b9050632afa533160e01b6001600160e01b031982160162001b38576000808080808080620019c9896004818d62002f42565b810190620019d8919062002f9f565b9650965096509650965096509650336001600160a01b0316876001600160a01b03161462001a195760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b038616301462001a435760405163750643af60e01b815260040160405180910390fd5b8a851462001a64576040516303fffc4b60e01b815260040160405180910390fd5b604080516001600160a01b0389811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180516001600160e01b031663d505accf60e01b1790529151918e169162001ae4919062002a14565b6000604051808303816000865af19150503d806000811462001b23576040519150601f19603f3d011682016040523d82523d6000602084013e62001b28565b606091505b50505050505050505050620006d9565b6001600160e01b031981166323f2ebc360e21b1462001b6a57604051637141605d60e11b815260040160405180910390fd5b60008080808080808062001b828a6004818e62002f42565b81019062001b91919062002ffa565b97509750975097509750975097509750336001600160a01b0316886001600160a01b03161462001bd45760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b038716301462001bfe5760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b038a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180516001600160e01b03166323f2ebc360e21b1790529151918f169162001c87919062002a14565b6000604051808303816000865af19150503d806000811462001cc6576040519150601f19603f3d011682016040523d82523d6000602084013e62001ccb565b606091505b50505050505050505050505050505050565b6040516001600160a01b038085166024830152831660448201526064810182905262000f1e9085906323b872dd60e01b90608401620018b4565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b179052905160609160009182916001600160a01b0386169162001d60919062002a14565b600060405180830381855afa9150503d806000811462001d9d576040519150601f19603f3d011682016040523d82523d6000602084013e62001da2565b606091505b50915091508162001dd357604051806040016040528060078152602001664e4f5f4e414d4560c81b8152506200150e565b6200150e816200210b565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b179052905160609160009182916001600160a01b0386169162001e27919062002a14565b600060405180830381855afa9150503d806000811462001e64576040519150601f19603f3d011682016040523d82523d6000602084013e62001e69565b606091505b50915091508162001dd357604051806040016040528060098152602001681393d7d4d6535093d360ba1b8152506200150e565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b0386169162001ee4919062002a14565b600060405180830381855afa9150503d806000811462001f21576040519150601f19603f3d011682016040523d82523d6000602084013e62001f26565b606091505b509150915081801562001f3a575080516020145b62001f475760126200150e565b808060200190518101906200150e919062003086565b60018055565b60685460ff1662001f8757604051635386698160e01b815260040160405180910390fd5b6068805460ff191690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b390600090a1565b600881901c60008181526069602052604081208054600160ff861690811b91821892839055929091908183169003620006d957604051630c8d9eab60e31b815260040160405180910390fd5b60006200205f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620022b59092919063ffffffff16565b8051909150156200166c5780806020019051810190620020809190620030a6565b6200166c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000e44565b600054610100900460ff1662001f5d5760405162461bcd60e51b815260040162000e449062002ef7565b606060408251106200212d5781806020019051810190620005b39190620030c6565b8151602003620022825760005b6020811080156200216d57508281815181106200215b576200215b62002c7d565b01602001516001600160f81b03191615155b156200218857806200217f8162002ca9565b9150506200213a565b80600003620021c15750506040805180820190915260128152714e4f545f56414c49445f454e434f44494e4760701b6020820152919050565b60008167ffffffffffffffff811115620021df57620021df620029d8565b6040519080825280601f01601f1916602001820160405280156200220a576020820181803683370190505b50905060005b828110156200227a578481815181106200222e576200222e62002c7d565b602001015160f81c60f81b8282815181106200224e576200224e62002c7d565b60200101906001600160f81b031916908160001a90535080620022718162002ca9565b91505062002210565b509392505050565b50506040805180820190915260128152714e4f545f56414c49445f454e434f44494e4760701b602082015290565b919050565b60606200150e848460008585600080866001600160a01b03168587604051620022df919062002a14565b60006040518083038185875af1925050503d80600081146200231e576040519150601f19603f3d011682016040523d82523d6000602084013e62002323565b606091505b5091509150620023368783838762002341565b979650505050505050565b60608315620023b5578251600003620023ad576001600160a01b0385163b620023ad5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000e44565b50816200150e565b6200150e8383815115620023cc5781518083602001fd5b8060405162461bcd60e51b815260040162000e44919062003146565b6115b2806200315c83390190565b803563ffffffff81168114620022b057600080fd5b6001600160a01b03811681146200242157600080fd5b50565b600080604083850312156200243857600080fd5b6200244383620023f6565b9150602083013562002455816200240b565b809150509250929050565b80151581146200242157600080fd5b60008083601f8401126200248257600080fd5b50813567ffffffffffffffff8111156200249b57600080fd5b602083019150836020828501011115620024b457600080fd5b9250929050565b600080600080600060808688031215620024d457600080fd5b620024df86620023f6565b94506020860135620024f1816200240b565b93506040860135620025038162002460565b9250606086013567ffffffffffffffff8111156200252057600080fd5b6200252e888289016200246f565b969995985093965092949392505050565b806104008101831015620005b357600080fd5b60008060008060008060008060008060006105208c8e0312156200257557600080fd5b620025818d8d6200253f565b9a50620025926104008d01620023f6565b99506104208c013598506104408c01359750620025b36104608d01620023f6565b96506104808c0135620025c6816200240b565b9550620025d76104a08d01620023f6565b94506104c08c0135620025ea816200240b565b93506104e08c013592506105008c013567ffffffffffffffff8111156200261057600080fd5b6200261e8e828f016200246f565b915080935050809150509295989b509295989b9093969950565b6000602082840312156200264b57600080fd5b813562002658816200240b565b9392505050565b60ff811681146200242157600080fd5b600080600080600080600060e0888a0312156200268b57600080fd5b873562002698816200265f565b9650620026a860208901620023f6565b95506040880135620026ba816200240b565b9450620026ca60608901620023f6565b93506080880135620026dc816200240b565b9699959850939692959460a0840135945060c09093013592915050565b6000806000606084860312156200270f57600080fd5b6200271a84620023f6565b925060208401356200272c816200240b565b915060408401356200273e816200240b565b809150509250925092565b6000602082840312156200275c57600080fd5b5035919050565b600080600080600080600060a0888a0312156200277f57600080fd5b6200278a88620023f6565b965060208801356200279c816200240b565b9550604088013567ffffffffffffffff80821115620027ba57600080fd5b620027c88b838c016200246f565b909750955060608a0135915080821115620027e257600080fd5b50620027f18a828b016200246f565b909450925050608088013562002807816200265f565b8091505092959891949750929550565b600080600080600080600060c0888a0312156200283357600080fd5b6200283e88620023f6565b9650602088013562002850816200240b565b955060408801359450606088013562002869816200240b565b935060808801356200287b8162002460565b925060a088013567ffffffffffffffff8111156200289857600080fd5b620028a68a828b016200246f565b989b979a50959850939692959293505050565b6000806000806104608587031215620028d157600080fd5b84359350620028e486602087016200253f565b9250620028f56104208601620023f6565b939692955092936104400135925050565b60e09290921b6001600160e01b031916825260601b6001600160601b031916600482015260180190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60ff8a16815263ffffffff89811660208301526001600160a01b03898116604084015288821660608401528716608083015260a0820186905261010060c08301819052600091620029ae848301878962002930565b925080851660e085015250509a9950505050505050505050565b8183823760009101908152919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562002a0b578181015183820152602001620029f1565b50506000910152565b6000825162002a28818460208701620029ee565b9190910192915050565b604051601f8201601f1916810167ffffffffffffffff8111828210171562002a5e5762002a5e620029d8565b604052919050565b600067ffffffffffffffff82111562002a835762002a83620029d8565b50601f01601f191660200190565b600082601f83011262002aa357600080fd5b813562002aba62002ab48262002a66565b62002a32565b81815284602083860101111562002ad057600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121562002b0357600080fd5b833567ffffffffffffffff8082111562002b1c57600080fd5b62002b2a8783880162002a91565b9450602086013591508082111562002b4157600080fd5b5062002b508682870162002a91565b92505060408401356200273e816200265f565b6000815180845262002b7d816020860160208601620029ee565b601f01601f19169290920160200192915050565b60608152600062002ba6606083018662002b63565b828103602084015262002bba818662002b63565b91505060ff83166040830152949350505050565b63ffffffff861681526001600160a01b0385811660208301528416604082015260806060820181905260009062002336908301848662002930565b63ffffffff95861681529390941660208401526001600160a01b039182166040840152166060820152608081019190915260a00190565b6001600160a01b038516815263ffffffff8416602082015260606040820181905260009062002c73908301848662002930565b9695505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820162002cbe5762002cbe62002c93565b5060010190565b60608152600062002cdb60608301878962002930565b828103602084015262002cf081868862002930565b91505060ff831660408301529695505050505050565b6000835162002d1a818460208801620029ee565b83519083019062002d30818360208801620029ee565b01949350505050565b60006020828403121562002d4c57600080fd5b5051919050565b81810381811115620005b357620005b362002c93565b60ff8916815263ffffffff88811660208301526001600160a01b03888116604084015287821660608401528616608083015260a0820185905261010060c0830181905260009162002dbd8483018762002b63565b925080851660e085015250509998505050505050505050565b600181815b8085111562002e1757816000190482111562002dfb5762002dfb62002c93565b8085161562002e0957918102915b93841c939080029062002ddb565b509250929050565b60008262002e3057506001620005b3565b8162002e3f57506000620005b3565b816001811462002e58576002811462002e635762002e83565b6001915050620005b3565b60ff84111562002e775762002e7762002c93565b50506001821b620005b3565b5060208310610133831016604e8410600b841016171562002ea8575081810a620005b3565b62002eb4838362002dd6565b806000190482111562002ecb5762002ecb62002c93565b029392505050565b600062002658838362002e1f565b634e487b7160e01b600052600160045260246000fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6000808585111562002f5357600080fd5b8386111562002f6157600080fd5b5050820193919092039150565b6001600160e01b0319813581811691600485101562002f975780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a03121562002fbb57600080fd5b873562002fc8816200240b565b9650602088013562002fda816200240b565b955060408801359450606088013593506080880135620026dc816200265f565b600080600080600080600080610100898b0312156200301857600080fd5b883562003025816200240b565b9750602089013562003037816200240b565b965060408901359550606089013594506080890135620030578162002460565b935060a089013562003069816200265f565b979a969950949793969295929450505060c08201359160e0013590565b6000602082840312156200309957600080fd5b815162002658816200265f565b600060208284031215620030b957600080fd5b8151620026588162002460565b600060208284031215620030d957600080fd5b815167ffffffffffffffff811115620030f157600080fd5b8201601f810184136200310357600080fd5b80516200311462002ab48262002a66565b8181528560208385010111156200312a57600080fd5b6200313d826020830160208601620029ee565b95945050505050565b60208152600062002658602083018462002b6356fe6101006040523480156200001257600080fd5b50604051620015b2380380620015b283398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516110f6620004bc60003960006101f70152600081816102ba015281816104e0015261054e0152600061049101526000818161031f015261045b01526110f66000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806370a08231116100b8578063a457c2d71161007c578063a457c2d7146102f4578063a9059cbb14610307578063cd0d00961461031a578063d505accf14610341578063dd62ed3e14610354578063ffa1ad741461036757600080fd5b806370a08231146102515780637ecebe001461027a57806395d89b411461029a5780639dc29fac146102a2578063a3c573eb146102b557600080fd5b806330adf81f116100ff57806330adf81f146101c9578063313ce567146101f05780633644e51514610221578063395093511461022957806340c10f191461023c57600080fd5b806306fdde031461013c578063095ea7b31461015a57806318160ddd1461017d57806320606b701461018f57806323b872dd146101b6575b600080fd5b610144610387565b6040516101519190610e5c565b60405180910390f35b61016d610168366004610ec6565b610419565b6040519015158152602001610151565b6002545b604051908152602001610151565b6101817f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b61016d6101c4366004610ef0565b610433565b6101817f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610151565b610181610457565b61016d610237366004610ec6565b6104b3565b61024f61024a366004610ec6565b6104d5565b005b61018161025f366004610f2c565b6001600160a01b031660009081526020819052604090205490565b610181610288366004610f2c565b60056020526000908152604090205481565b610144610534565b61024f6102b0366004610ec6565b610543565b6102dc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610151565b61016d610302366004610ec6565b610595565b61016d610315366004610ec6565b610610565b6101817f000000000000000000000000000000000000000000000000000000000000000081565b61024f61034f366004610f4e565b61061e565b610181610362366004610fc1565b610859565b610144604051806040016040528060018152602001603160f81b81525081565b60606003805461039690610ff4565b80601f01602080910402602001604051908101604052809291908181526020018280546103c290610ff4565b801561040f5780601f106103e45761010080835404028352916020019161040f565b820191906000526020600020905b8154815290600101906020018083116103f257829003601f168201915b5050505050905090565b600033610427818585610884565b60019150505b92915050565b6000336104418582856109a9565b61044c858585610a23565b506001949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000461461048e5761048946610bc7565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b6000336104278185856104c68383610859565b6104d09190611044565b610884565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105265760405162461bcd60e51b815260040161051d90611057565b60405180910390fd5b6105308282610c73565b5050565b60606004805461039690610ff4565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461058b5760405162461bcd60e51b815260040161051d90611057565b6105308282610d32565b600033816105a38286610859565b9050838110156106035760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161051d565b61044c8286868403610884565b600033610427818585610a23565b8342111561067a5760405162461bcd60e51b8152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a20457870697265642070656044820152631c9b5a5d60e21b606482015260840161051d565b6001600160a01b038716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866106c7836110a7565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610725610457565b60405161190160f01b602082015260228101919091526042810183905260620160408051601f198184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa1580156107b0573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906107e65750896001600160a01b0316816001600160a01b0316145b6108425760405162461bcd60e51b815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c6964207369604482015266676e617475726560c81b606482015260840161051d565b61084d8a8a8a610884565b50505050505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b0383166108e65760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161051d565b6001600160a01b0382166109475760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161051d565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60006109b58484610859565b90506000198114610a1d5781811015610a105760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161051d565b610a1d8484848403610884565b50505050565b6001600160a01b038316610a875760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161051d565b6001600160a01b038216610ae95760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161051d565b6001600160a01b03831660009081526020819052604090205481811015610b615760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161051d565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610a1d565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f610bf2610387565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6001600160a01b038216610cc95760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161051d565b8060026000828254610cdb9190611044565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b038216610d925760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161051d565b6001600160a01b03821660009081526020819052604090205481811015610e065760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161051d565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910161099c565b600060208083528351808285015260005b81811015610e8957858101830151858201604001528201610e6d565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610ec157600080fd5b919050565b60008060408385031215610ed957600080fd5b610ee283610eaa565b946020939093013593505050565b600080600060608486031215610f0557600080fd5b610f0e84610eaa565b9250610f1c60208501610eaa565b9150604084013590509250925092565b600060208284031215610f3e57600080fd5b610f4782610eaa565b9392505050565b600080600080600080600060e0888a031215610f6957600080fd5b610f7288610eaa565b9650610f8060208901610eaa565b95506040880135945060608801359350608088013560ff81168114610fa457600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215610fd457600080fd5b610fdd83610eaa565b9150610feb60208401610eaa565b90509250929050565b600181811c9082168061100857607f821691505b60208210810361102857634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561042d5761042d61102e565b60208082526030908201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60408201526f6c79676f6e5a6b45564d42726964676560801b606082015260800190565b6000600182016110b9576110b961102e565b506001019056fea2646970667358221220e578d8e4b71a5c98739e7f11de9b62b5bff7c0ec9d1c2013a5019efa3df3a96d64736f6c63430008140033a2646970667358221220a5db4ca599c25af724716ede251c43e562514e0970d03b930b42a70d351d54b164736f6c63430008140033", +} + +// LegacyABI is the input ABI used to generate the binding from. +// Deprecated: Use LegacyMetaData.ABI instead. +var LegacyABI = LegacyMetaData.ABI + +// LegacyBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use LegacyMetaData.Bin instead. +var LegacyBin = LegacyMetaData.Bin + +// DeployLegacy deploys a new Ethereum contract, binding an instance of Legacy to it. +func DeployLegacy(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Legacy, error) { + parsed, err := LegacyMetaData.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(LegacyBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Legacy{LegacyCaller: LegacyCaller{contract: contract}, LegacyTransactor: LegacyTransactor{contract: contract}, LegacyFilterer: LegacyFilterer{contract: contract}}, nil +} + +// Legacy is an auto generated Go binding around an Ethereum contract. +type Legacy struct { + LegacyCaller // Read-only binding to the contract + LegacyTransactor // Write-only binding to the contract + LegacyFilterer // Log filterer for contract events +} + +// LegacyCaller is an auto generated read-only Go binding around an Ethereum contract. +type LegacyCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LegacyTransactor is an auto generated write-only Go binding around an Ethereum contract. +type LegacyTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LegacyFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type LegacyFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// LegacySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type LegacySession struct { + Contract *Legacy // 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 +} + +// LegacyCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type LegacyCallerSession struct { + Contract *LegacyCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// LegacyTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type LegacyTransactorSession struct { + Contract *LegacyTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// LegacyRaw is an auto generated low-level Go binding around an Ethereum contract. +type LegacyRaw struct { + Contract *Legacy // Generic contract binding to access the raw methods on +} + +// LegacyCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type LegacyCallerRaw struct { + Contract *LegacyCaller // Generic read-only contract binding to access the raw methods on +} + +// LegacyTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type LegacyTransactorRaw struct { + Contract *LegacyTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewLegacy creates a new instance of Legacy, bound to a specific deployed contract. +func NewLegacy(address common.Address, backend bind.ContractBackend) (*Legacy, error) { + contract, err := bindLegacy(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Legacy{LegacyCaller: LegacyCaller{contract: contract}, LegacyTransactor: LegacyTransactor{contract: contract}, LegacyFilterer: LegacyFilterer{contract: contract}}, nil +} + +// NewLegacyCaller creates a new read-only instance of Legacy, bound to a specific deployed contract. +func NewLegacyCaller(address common.Address, caller bind.ContractCaller) (*LegacyCaller, error) { + contract, err := bindLegacy(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &LegacyCaller{contract: contract}, nil +} + +// NewLegacyTransactor creates a new write-only instance of Legacy, bound to a specific deployed contract. +func NewLegacyTransactor(address common.Address, transactor bind.ContractTransactor) (*LegacyTransactor, error) { + contract, err := bindLegacy(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &LegacyTransactor{contract: contract}, nil +} + +// NewLegacyFilterer creates a new log filterer instance of Legacy, bound to a specific deployed contract. +func NewLegacyFilterer(address common.Address, filterer bind.ContractFilterer) (*LegacyFilterer, error) { + contract, err := bindLegacy(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &LegacyFilterer{contract: contract}, nil +} + +// bindLegacy binds a generic wrapper to an already deployed contract. +func bindLegacy(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := LegacyMetaData.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 (_Legacy *LegacyRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Legacy.Contract.LegacyCaller.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 (_Legacy *LegacyRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Legacy.Contract.LegacyTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Legacy *LegacyRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Legacy.Contract.LegacyTransactor.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 (_Legacy *LegacyCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Legacy.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 (_Legacy *LegacyTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Legacy.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Legacy *LegacyTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Legacy.Contract.contract.Transact(opts, method, params...) +} + +// ClaimedBitMap is a free data retrieval call binding the contract method 0xee25560b. +// +// Solidity: function claimedBitMap(uint256 ) view returns(uint256) +func (_Legacy *LegacyCaller) ClaimedBitMap(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "claimedBitMap", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ClaimedBitMap is a free data retrieval call binding the contract method 0xee25560b. +// +// Solidity: function claimedBitMap(uint256 ) view returns(uint256) +func (_Legacy *LegacySession) ClaimedBitMap(arg0 *big.Int) (*big.Int, error) { + return _Legacy.Contract.ClaimedBitMap(&_Legacy.CallOpts, arg0) +} + +// ClaimedBitMap is a free data retrieval call binding the contract method 0xee25560b. +// +// Solidity: function claimedBitMap(uint256 ) view returns(uint256) +func (_Legacy *LegacyCallerSession) ClaimedBitMap(arg0 *big.Int) (*big.Int, error) { + return _Legacy.Contract.ClaimedBitMap(&_Legacy.CallOpts, arg0) +} + +// DepositCount is a free data retrieval call binding the contract method 0x2dfdf0b5. +// +// Solidity: function depositCount() view returns(uint256) +func (_Legacy *LegacyCaller) DepositCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "depositCount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// DepositCount is a free data retrieval call binding the contract method 0x2dfdf0b5. +// +// Solidity: function depositCount() view returns(uint256) +func (_Legacy *LegacySession) DepositCount() (*big.Int, error) { + return _Legacy.Contract.DepositCount(&_Legacy.CallOpts) +} + +// DepositCount is a free data retrieval call binding the contract method 0x2dfdf0b5. +// +// Solidity: function depositCount() view returns(uint256) +func (_Legacy *LegacyCallerSession) DepositCount() (*big.Int, error) { + return _Legacy.Contract.DepositCount(&_Legacy.CallOpts) +} + +// GetDepositRoot is a free data retrieval call binding the contract method 0x3ae05047. +// +// Solidity: function getDepositRoot() view returns(bytes32) +func (_Legacy *LegacyCaller) GetDepositRoot(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "getDepositRoot") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetDepositRoot is a free data retrieval call binding the contract method 0x3ae05047. +// +// Solidity: function getDepositRoot() view returns(bytes32) +func (_Legacy *LegacySession) GetDepositRoot() ([32]byte, error) { + return _Legacy.Contract.GetDepositRoot(&_Legacy.CallOpts) +} + +// GetDepositRoot is a free data retrieval call binding the contract method 0x3ae05047. +// +// Solidity: function getDepositRoot() view returns(bytes32) +func (_Legacy *LegacyCallerSession) GetDepositRoot() ([32]byte, error) { + return _Legacy.Contract.GetDepositRoot(&_Legacy.CallOpts) +} + +// GetLeafValue is a free data retrieval call binding the contract method 0x3e197043. +// +// Solidity: function getLeafValue(uint8 leafType, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes32 metadataHash) pure returns(bytes32) +func (_Legacy *LegacyCaller) GetLeafValue(opts *bind.CallOpts, leafType uint8, originNetwork uint32, originAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadataHash [32]byte) ([32]byte, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "getLeafValue", leafType, originNetwork, originAddress, destinationNetwork, destinationAddress, amount, metadataHash) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetLeafValue is a free data retrieval call binding the contract method 0x3e197043. +// +// Solidity: function getLeafValue(uint8 leafType, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes32 metadataHash) pure returns(bytes32) +func (_Legacy *LegacySession) GetLeafValue(leafType uint8, originNetwork uint32, originAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadataHash [32]byte) ([32]byte, error) { + return _Legacy.Contract.GetLeafValue(&_Legacy.CallOpts, leafType, originNetwork, originAddress, destinationNetwork, destinationAddress, amount, metadataHash) +} + +// GetLeafValue is a free data retrieval call binding the contract method 0x3e197043. +// +// Solidity: function getLeafValue(uint8 leafType, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes32 metadataHash) pure returns(bytes32) +func (_Legacy *LegacyCallerSession) GetLeafValue(leafType uint8, originNetwork uint32, originAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadataHash [32]byte) ([32]byte, error) { + return _Legacy.Contract.GetLeafValue(&_Legacy.CallOpts, leafType, originNetwork, originAddress, destinationNetwork, destinationAddress, amount, metadataHash) +} + +// GetTokenWrappedAddress is a free data retrieval call binding the contract method 0x22e95f2c. +// +// Solidity: function getTokenWrappedAddress(uint32 originNetwork, address originTokenAddress) view returns(address) +func (_Legacy *LegacyCaller) GetTokenWrappedAddress(opts *bind.CallOpts, originNetwork uint32, originTokenAddress common.Address) (common.Address, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "getTokenWrappedAddress", originNetwork, originTokenAddress) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetTokenWrappedAddress is a free data retrieval call binding the contract method 0x22e95f2c. +// +// Solidity: function getTokenWrappedAddress(uint32 originNetwork, address originTokenAddress) view returns(address) +func (_Legacy *LegacySession) GetTokenWrappedAddress(originNetwork uint32, originTokenAddress common.Address) (common.Address, error) { + return _Legacy.Contract.GetTokenWrappedAddress(&_Legacy.CallOpts, originNetwork, originTokenAddress) +} + +// GetTokenWrappedAddress is a free data retrieval call binding the contract method 0x22e95f2c. +// +// Solidity: function getTokenWrappedAddress(uint32 originNetwork, address originTokenAddress) view returns(address) +func (_Legacy *LegacyCallerSession) GetTokenWrappedAddress(originNetwork uint32, originTokenAddress common.Address) (common.Address, error) { + return _Legacy.Contract.GetTokenWrappedAddress(&_Legacy.CallOpts, originNetwork, originTokenAddress) +} + +// GlobalExitRootManager is a free data retrieval call binding the contract method 0xd02103ca. +// +// Solidity: function globalExitRootManager() view returns(address) +func (_Legacy *LegacyCaller) GlobalExitRootManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "globalExitRootManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GlobalExitRootManager is a free data retrieval call binding the contract method 0xd02103ca. +// +// Solidity: function globalExitRootManager() view returns(address) +func (_Legacy *LegacySession) GlobalExitRootManager() (common.Address, error) { + return _Legacy.Contract.GlobalExitRootManager(&_Legacy.CallOpts) +} + +// GlobalExitRootManager is a free data retrieval call binding the contract method 0xd02103ca. +// +// Solidity: function globalExitRootManager() view returns(address) +func (_Legacy *LegacyCallerSession) GlobalExitRootManager() (common.Address, error) { + return _Legacy.Contract.GlobalExitRootManager(&_Legacy.CallOpts) +} + +// IsClaimed is a free data retrieval call binding the contract method 0x9e34070f. +// +// Solidity: function isClaimed(uint256 index) view returns(bool) +func (_Legacy *LegacyCaller) IsClaimed(opts *bind.CallOpts, index *big.Int) (bool, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "isClaimed", index) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsClaimed is a free data retrieval call binding the contract method 0x9e34070f. +// +// Solidity: function isClaimed(uint256 index) view returns(bool) +func (_Legacy *LegacySession) IsClaimed(index *big.Int) (bool, error) { + return _Legacy.Contract.IsClaimed(&_Legacy.CallOpts, index) +} + +// IsClaimed is a free data retrieval call binding the contract method 0x9e34070f. +// +// Solidity: function isClaimed(uint256 index) view returns(bool) +func (_Legacy *LegacyCallerSession) IsClaimed(index *big.Int) (bool, error) { + return _Legacy.Contract.IsClaimed(&_Legacy.CallOpts, index) +} + +// IsEmergencyState is a free data retrieval call binding the contract method 0x15064c96. +// +// Solidity: function isEmergencyState() view returns(bool) +func (_Legacy *LegacyCaller) IsEmergencyState(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "isEmergencyState") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsEmergencyState is a free data retrieval call binding the contract method 0x15064c96. +// +// Solidity: function isEmergencyState() view returns(bool) +func (_Legacy *LegacySession) IsEmergencyState() (bool, error) { + return _Legacy.Contract.IsEmergencyState(&_Legacy.CallOpts) +} + +// IsEmergencyState is a free data retrieval call binding the contract method 0x15064c96. +// +// Solidity: function isEmergencyState() view returns(bool) +func (_Legacy *LegacyCallerSession) IsEmergencyState() (bool, error) { + return _Legacy.Contract.IsEmergencyState(&_Legacy.CallOpts) +} + +// LastUpdatedDepositCount is a free data retrieval call binding the contract method 0xbe5831c7. +// +// Solidity: function lastUpdatedDepositCount() view returns(uint32) +func (_Legacy *LegacyCaller) LastUpdatedDepositCount(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "lastUpdatedDepositCount") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// LastUpdatedDepositCount is a free data retrieval call binding the contract method 0xbe5831c7. +// +// Solidity: function lastUpdatedDepositCount() view returns(uint32) +func (_Legacy *LegacySession) LastUpdatedDepositCount() (uint32, error) { + return _Legacy.Contract.LastUpdatedDepositCount(&_Legacy.CallOpts) +} + +// LastUpdatedDepositCount is a free data retrieval call binding the contract method 0xbe5831c7. +// +// Solidity: function lastUpdatedDepositCount() view returns(uint32) +func (_Legacy *LegacyCallerSession) LastUpdatedDepositCount() (uint32, error) { + return _Legacy.Contract.LastUpdatedDepositCount(&_Legacy.CallOpts) +} + +// NetworkID is a free data retrieval call binding the contract method 0xbab161bf. +// +// Solidity: function networkID() view returns(uint32) +func (_Legacy *LegacyCaller) NetworkID(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "networkID") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// NetworkID is a free data retrieval call binding the contract method 0xbab161bf. +// +// Solidity: function networkID() view returns(uint32) +func (_Legacy *LegacySession) NetworkID() (uint32, error) { + return _Legacy.Contract.NetworkID(&_Legacy.CallOpts) +} + +// NetworkID is a free data retrieval call binding the contract method 0xbab161bf. +// +// Solidity: function networkID() view returns(uint32) +func (_Legacy *LegacyCallerSession) NetworkID() (uint32, error) { + return _Legacy.Contract.NetworkID(&_Legacy.CallOpts) +} + +// PolygonZkEVMaddress is a free data retrieval call binding the contract method 0x34ac9cf2. +// +// Solidity: function polygonZkEVMaddress() view returns(address) +func (_Legacy *LegacyCaller) PolygonZkEVMaddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "polygonZkEVMaddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PolygonZkEVMaddress is a free data retrieval call binding the contract method 0x34ac9cf2. +// +// Solidity: function polygonZkEVMaddress() view returns(address) +func (_Legacy *LegacySession) PolygonZkEVMaddress() (common.Address, error) { + return _Legacy.Contract.PolygonZkEVMaddress(&_Legacy.CallOpts) +} + +// PolygonZkEVMaddress is a free data retrieval call binding the contract method 0x34ac9cf2. +// +// Solidity: function polygonZkEVMaddress() view returns(address) +func (_Legacy *LegacyCallerSession) PolygonZkEVMaddress() (common.Address, error) { + return _Legacy.Contract.PolygonZkEVMaddress(&_Legacy.CallOpts) +} + +// PrecalculatedWrapperAddress is a free data retrieval call binding the contract method 0xaaa13cc2. +// +// Solidity: function precalculatedWrapperAddress(uint32 originNetwork, address originTokenAddress, string name, string symbol, uint8 decimals) view returns(address) +func (_Legacy *LegacyCaller) PrecalculatedWrapperAddress(opts *bind.CallOpts, originNetwork uint32, originTokenAddress common.Address, name string, symbol string, decimals uint8) (common.Address, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "precalculatedWrapperAddress", originNetwork, originTokenAddress, name, symbol, decimals) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PrecalculatedWrapperAddress is a free data retrieval call binding the contract method 0xaaa13cc2. +// +// Solidity: function precalculatedWrapperAddress(uint32 originNetwork, address originTokenAddress, string name, string symbol, uint8 decimals) view returns(address) +func (_Legacy *LegacySession) PrecalculatedWrapperAddress(originNetwork uint32, originTokenAddress common.Address, name string, symbol string, decimals uint8) (common.Address, error) { + return _Legacy.Contract.PrecalculatedWrapperAddress(&_Legacy.CallOpts, originNetwork, originTokenAddress, name, symbol, decimals) +} + +// PrecalculatedWrapperAddress is a free data retrieval call binding the contract method 0xaaa13cc2. +// +// Solidity: function precalculatedWrapperAddress(uint32 originNetwork, address originTokenAddress, string name, string symbol, uint8 decimals) view returns(address) +func (_Legacy *LegacyCallerSession) PrecalculatedWrapperAddress(originNetwork uint32, originTokenAddress common.Address, name string, symbol string, decimals uint8) (common.Address, error) { + return _Legacy.Contract.PrecalculatedWrapperAddress(&_Legacy.CallOpts, originNetwork, originTokenAddress, name, symbol, decimals) +} + +// TokenInfoToWrappedToken is a free data retrieval call binding the contract method 0x81b1c174. +// +// Solidity: function tokenInfoToWrappedToken(bytes32 ) view returns(address) +func (_Legacy *LegacyCaller) TokenInfoToWrappedToken(opts *bind.CallOpts, arg0 [32]byte) (common.Address, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "tokenInfoToWrappedToken", arg0) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// TokenInfoToWrappedToken is a free data retrieval call binding the contract method 0x81b1c174. +// +// Solidity: function tokenInfoToWrappedToken(bytes32 ) view returns(address) +func (_Legacy *LegacySession) TokenInfoToWrappedToken(arg0 [32]byte) (common.Address, error) { + return _Legacy.Contract.TokenInfoToWrappedToken(&_Legacy.CallOpts, arg0) +} + +// TokenInfoToWrappedToken is a free data retrieval call binding the contract method 0x81b1c174. +// +// Solidity: function tokenInfoToWrappedToken(bytes32 ) view returns(address) +func (_Legacy *LegacyCallerSession) TokenInfoToWrappedToken(arg0 [32]byte) (common.Address, error) { + return _Legacy.Contract.TokenInfoToWrappedToken(&_Legacy.CallOpts, arg0) +} + +// VerifyMerkleProof is a free data retrieval call binding the contract method 0xfb570834. +// +// Solidity: function verifyMerkleProof(bytes32 leafHash, bytes32[32] smtProof, uint32 index, bytes32 root) pure returns(bool) +func (_Legacy *LegacyCaller) VerifyMerkleProof(opts *bind.CallOpts, leafHash [32]byte, smtProof [32][32]byte, index uint32, root [32]byte) (bool, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "verifyMerkleProof", leafHash, smtProof, index, root) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// VerifyMerkleProof is a free data retrieval call binding the contract method 0xfb570834. +// +// Solidity: function verifyMerkleProof(bytes32 leafHash, bytes32[32] smtProof, uint32 index, bytes32 root) pure returns(bool) +func (_Legacy *LegacySession) VerifyMerkleProof(leafHash [32]byte, smtProof [32][32]byte, index uint32, root [32]byte) (bool, error) { + return _Legacy.Contract.VerifyMerkleProof(&_Legacy.CallOpts, leafHash, smtProof, index, root) +} + +// VerifyMerkleProof is a free data retrieval call binding the contract method 0xfb570834. +// +// Solidity: function verifyMerkleProof(bytes32 leafHash, bytes32[32] smtProof, uint32 index, bytes32 root) pure returns(bool) +func (_Legacy *LegacyCallerSession) VerifyMerkleProof(leafHash [32]byte, smtProof [32][32]byte, index uint32, root [32]byte) (bool, error) { + return _Legacy.Contract.VerifyMerkleProof(&_Legacy.CallOpts, leafHash, smtProof, index, root) +} + +// WrappedTokenToTokenInfo is a free data retrieval call binding the contract method 0x318aee3d. +// +// Solidity: function wrappedTokenToTokenInfo(address ) view returns(uint32 originNetwork, address originTokenAddress) +func (_Legacy *LegacyCaller) WrappedTokenToTokenInfo(opts *bind.CallOpts, arg0 common.Address) (struct { + OriginNetwork uint32 + OriginTokenAddress common.Address +}, error) { + var out []interface{} + err := _Legacy.contract.Call(opts, &out, "wrappedTokenToTokenInfo", arg0) + + outstruct := new(struct { + OriginNetwork uint32 + OriginTokenAddress common.Address + }) + if err != nil { + return *outstruct, err + } + + outstruct.OriginNetwork = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.OriginTokenAddress = *abi.ConvertType(out[1], new(common.Address)).(*common.Address) + + return *outstruct, err + +} + +// WrappedTokenToTokenInfo is a free data retrieval call binding the contract method 0x318aee3d. +// +// Solidity: function wrappedTokenToTokenInfo(address ) view returns(uint32 originNetwork, address originTokenAddress) +func (_Legacy *LegacySession) WrappedTokenToTokenInfo(arg0 common.Address) (struct { + OriginNetwork uint32 + OriginTokenAddress common.Address +}, error) { + return _Legacy.Contract.WrappedTokenToTokenInfo(&_Legacy.CallOpts, arg0) +} + +// WrappedTokenToTokenInfo is a free data retrieval call binding the contract method 0x318aee3d. +// +// Solidity: function wrappedTokenToTokenInfo(address ) view returns(uint32 originNetwork, address originTokenAddress) +func (_Legacy *LegacyCallerSession) WrappedTokenToTokenInfo(arg0 common.Address) (struct { + OriginNetwork uint32 + OriginTokenAddress common.Address +}, error) { + return _Legacy.Contract.WrappedTokenToTokenInfo(&_Legacy.CallOpts, arg0) +} + +// ActivateEmergencyState is a paid mutator transaction binding the contract method 0x2072f6c5. +// +// Solidity: function activateEmergencyState() returns() +func (_Legacy *LegacyTransactor) ActivateEmergencyState(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Legacy.contract.Transact(opts, "activateEmergencyState") +} + +// ActivateEmergencyState is a paid mutator transaction binding the contract method 0x2072f6c5. +// +// Solidity: function activateEmergencyState() returns() +func (_Legacy *LegacySession) ActivateEmergencyState() (*types.Transaction, error) { + return _Legacy.Contract.ActivateEmergencyState(&_Legacy.TransactOpts) +} + +// ActivateEmergencyState is a paid mutator transaction binding the contract method 0x2072f6c5. +// +// Solidity: function activateEmergencyState() returns() +func (_Legacy *LegacyTransactorSession) ActivateEmergencyState() (*types.Transaction, error) { + return _Legacy.Contract.ActivateEmergencyState(&_Legacy.TransactOpts) +} + +// BridgeAsset is a paid mutator transaction binding the contract method 0xcd586579. +// +// Solidity: function bridgeAsset(uint32 destinationNetwork, address destinationAddress, uint256 amount, address token, bool forceUpdateGlobalExitRoot, bytes permitData) payable returns() +func (_Legacy *LegacyTransactor) BridgeAsset(opts *bind.TransactOpts, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, token common.Address, forceUpdateGlobalExitRoot bool, permitData []byte) (*types.Transaction, error) { + return _Legacy.contract.Transact(opts, "bridgeAsset", destinationNetwork, destinationAddress, amount, token, forceUpdateGlobalExitRoot, permitData) +} + +// BridgeAsset is a paid mutator transaction binding the contract method 0xcd586579. +// +// Solidity: function bridgeAsset(uint32 destinationNetwork, address destinationAddress, uint256 amount, address token, bool forceUpdateGlobalExitRoot, bytes permitData) payable returns() +func (_Legacy *LegacySession) BridgeAsset(destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, token common.Address, forceUpdateGlobalExitRoot bool, permitData []byte) (*types.Transaction, error) { + return _Legacy.Contract.BridgeAsset(&_Legacy.TransactOpts, destinationNetwork, destinationAddress, amount, token, forceUpdateGlobalExitRoot, permitData) +} + +// BridgeAsset is a paid mutator transaction binding the contract method 0xcd586579. +// +// Solidity: function bridgeAsset(uint32 destinationNetwork, address destinationAddress, uint256 amount, address token, bool forceUpdateGlobalExitRoot, bytes permitData) payable returns() +func (_Legacy *LegacyTransactorSession) BridgeAsset(destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, token common.Address, forceUpdateGlobalExitRoot bool, permitData []byte) (*types.Transaction, error) { + return _Legacy.Contract.BridgeAsset(&_Legacy.TransactOpts, destinationNetwork, destinationAddress, amount, token, forceUpdateGlobalExitRoot, permitData) +} + +// BridgeMessage is a paid mutator transaction binding the contract method 0x240ff378. +// +// Solidity: function bridgeMessage(uint32 destinationNetwork, address destinationAddress, bool forceUpdateGlobalExitRoot, bytes metadata) payable returns() +func (_Legacy *LegacyTransactor) BridgeMessage(opts *bind.TransactOpts, destinationNetwork uint32, destinationAddress common.Address, forceUpdateGlobalExitRoot bool, metadata []byte) (*types.Transaction, error) { + return _Legacy.contract.Transact(opts, "bridgeMessage", destinationNetwork, destinationAddress, forceUpdateGlobalExitRoot, metadata) +} + +// BridgeMessage is a paid mutator transaction binding the contract method 0x240ff378. +// +// Solidity: function bridgeMessage(uint32 destinationNetwork, address destinationAddress, bool forceUpdateGlobalExitRoot, bytes metadata) payable returns() +func (_Legacy *LegacySession) BridgeMessage(destinationNetwork uint32, destinationAddress common.Address, forceUpdateGlobalExitRoot bool, metadata []byte) (*types.Transaction, error) { + return _Legacy.Contract.BridgeMessage(&_Legacy.TransactOpts, destinationNetwork, destinationAddress, forceUpdateGlobalExitRoot, metadata) +} + +// BridgeMessage is a paid mutator transaction binding the contract method 0x240ff378. +// +// Solidity: function bridgeMessage(uint32 destinationNetwork, address destinationAddress, bool forceUpdateGlobalExitRoot, bytes metadata) payable returns() +func (_Legacy *LegacyTransactorSession) BridgeMessage(destinationNetwork uint32, destinationAddress common.Address, forceUpdateGlobalExitRoot bool, metadata []byte) (*types.Transaction, error) { + return _Legacy.Contract.BridgeMessage(&_Legacy.TransactOpts, destinationNetwork, destinationAddress, forceUpdateGlobalExitRoot, metadata) +} + +// ClaimAsset is a paid mutator transaction binding the contract method 0x2cffd02e. +// +// Solidity: function claimAsset(bytes32[32] smtProof, uint32 index, bytes32 mainnetExitRoot, bytes32 rollupExitRoot, uint32 originNetwork, address originTokenAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata) returns() +func (_Legacy *LegacyTransactor) ClaimAsset(opts *bind.TransactOpts, smtProof [32][32]byte, index uint32, mainnetExitRoot [32]byte, rollupExitRoot [32]byte, originNetwork uint32, originTokenAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadata []byte) (*types.Transaction, error) { + return _Legacy.contract.Transact(opts, "claimAsset", smtProof, index, mainnetExitRoot, rollupExitRoot, originNetwork, originTokenAddress, destinationNetwork, destinationAddress, amount, metadata) +} + +// ClaimAsset is a paid mutator transaction binding the contract method 0x2cffd02e. +// +// Solidity: function claimAsset(bytes32[32] smtProof, uint32 index, bytes32 mainnetExitRoot, bytes32 rollupExitRoot, uint32 originNetwork, address originTokenAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata) returns() +func (_Legacy *LegacySession) ClaimAsset(smtProof [32][32]byte, index uint32, mainnetExitRoot [32]byte, rollupExitRoot [32]byte, originNetwork uint32, originTokenAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadata []byte) (*types.Transaction, error) { + return _Legacy.Contract.ClaimAsset(&_Legacy.TransactOpts, smtProof, index, mainnetExitRoot, rollupExitRoot, originNetwork, originTokenAddress, destinationNetwork, destinationAddress, amount, metadata) +} + +// ClaimAsset is a paid mutator transaction binding the contract method 0x2cffd02e. +// +// Solidity: function claimAsset(bytes32[32] smtProof, uint32 index, bytes32 mainnetExitRoot, bytes32 rollupExitRoot, uint32 originNetwork, address originTokenAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata) returns() +func (_Legacy *LegacyTransactorSession) ClaimAsset(smtProof [32][32]byte, index uint32, mainnetExitRoot [32]byte, rollupExitRoot [32]byte, originNetwork uint32, originTokenAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadata []byte) (*types.Transaction, error) { + return _Legacy.Contract.ClaimAsset(&_Legacy.TransactOpts, smtProof, index, mainnetExitRoot, rollupExitRoot, originNetwork, originTokenAddress, destinationNetwork, destinationAddress, amount, metadata) +} + +// ClaimMessage is a paid mutator transaction binding the contract method 0x2d2c9d94. +// +// Solidity: function claimMessage(bytes32[32] smtProof, uint32 index, bytes32 mainnetExitRoot, bytes32 rollupExitRoot, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata) returns() +func (_Legacy *LegacyTransactor) ClaimMessage(opts *bind.TransactOpts, smtProof [32][32]byte, index uint32, mainnetExitRoot [32]byte, rollupExitRoot [32]byte, originNetwork uint32, originAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadata []byte) (*types.Transaction, error) { + return _Legacy.contract.Transact(opts, "claimMessage", smtProof, index, mainnetExitRoot, rollupExitRoot, originNetwork, originAddress, destinationNetwork, destinationAddress, amount, metadata) +} + +// ClaimMessage is a paid mutator transaction binding the contract method 0x2d2c9d94. +// +// Solidity: function claimMessage(bytes32[32] smtProof, uint32 index, bytes32 mainnetExitRoot, bytes32 rollupExitRoot, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata) returns() +func (_Legacy *LegacySession) ClaimMessage(smtProof [32][32]byte, index uint32, mainnetExitRoot [32]byte, rollupExitRoot [32]byte, originNetwork uint32, originAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadata []byte) (*types.Transaction, error) { + return _Legacy.Contract.ClaimMessage(&_Legacy.TransactOpts, smtProof, index, mainnetExitRoot, rollupExitRoot, originNetwork, originAddress, destinationNetwork, destinationAddress, amount, metadata) +} + +// ClaimMessage is a paid mutator transaction binding the contract method 0x2d2c9d94. +// +// Solidity: function claimMessage(bytes32[32] smtProof, uint32 index, bytes32 mainnetExitRoot, bytes32 rollupExitRoot, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata) returns() +func (_Legacy *LegacyTransactorSession) ClaimMessage(smtProof [32][32]byte, index uint32, mainnetExitRoot [32]byte, rollupExitRoot [32]byte, originNetwork uint32, originAddress common.Address, destinationNetwork uint32, destinationAddress common.Address, amount *big.Int, metadata []byte) (*types.Transaction, error) { + return _Legacy.Contract.ClaimMessage(&_Legacy.TransactOpts, smtProof, index, mainnetExitRoot, rollupExitRoot, originNetwork, originAddress, destinationNetwork, destinationAddress, amount, metadata) +} + +// DeactivateEmergencyState is a paid mutator transaction binding the contract method 0xdbc16976. +// +// Solidity: function deactivateEmergencyState() returns() +func (_Legacy *LegacyTransactor) DeactivateEmergencyState(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Legacy.contract.Transact(opts, "deactivateEmergencyState") +} + +// DeactivateEmergencyState is a paid mutator transaction binding the contract method 0xdbc16976. +// +// Solidity: function deactivateEmergencyState() returns() +func (_Legacy *LegacySession) DeactivateEmergencyState() (*types.Transaction, error) { + return _Legacy.Contract.DeactivateEmergencyState(&_Legacy.TransactOpts) +} + +// DeactivateEmergencyState is a paid mutator transaction binding the contract method 0xdbc16976. +// +// Solidity: function deactivateEmergencyState() returns() +func (_Legacy *LegacyTransactorSession) DeactivateEmergencyState() (*types.Transaction, error) { + return _Legacy.Contract.DeactivateEmergencyState(&_Legacy.TransactOpts) +} + +// Initialize is a paid mutator transaction binding the contract method 0x647c576c. +// +// Solidity: function initialize(uint32 _networkID, address _globalExitRootManager, address _polygonZkEVMaddress) returns() +func (_Legacy *LegacyTransactor) Initialize(opts *bind.TransactOpts, _networkID uint32, _globalExitRootManager common.Address, _polygonZkEVMaddress common.Address) (*types.Transaction, error) { + return _Legacy.contract.Transact(opts, "initialize", _networkID, _globalExitRootManager, _polygonZkEVMaddress) +} + +// Initialize is a paid mutator transaction binding the contract method 0x647c576c. +// +// Solidity: function initialize(uint32 _networkID, address _globalExitRootManager, address _polygonZkEVMaddress) returns() +func (_Legacy *LegacySession) Initialize(_networkID uint32, _globalExitRootManager common.Address, _polygonZkEVMaddress common.Address) (*types.Transaction, error) { + return _Legacy.Contract.Initialize(&_Legacy.TransactOpts, _networkID, _globalExitRootManager, _polygonZkEVMaddress) +} + +// Initialize is a paid mutator transaction binding the contract method 0x647c576c. +// +// Solidity: function initialize(uint32 _networkID, address _globalExitRootManager, address _polygonZkEVMaddress) returns() +func (_Legacy *LegacyTransactorSession) Initialize(_networkID uint32, _globalExitRootManager common.Address, _polygonZkEVMaddress common.Address) (*types.Transaction, error) { + return _Legacy.Contract.Initialize(&_Legacy.TransactOpts, _networkID, _globalExitRootManager, _polygonZkEVMaddress) +} + +// UpdateGlobalExitRoot is a paid mutator transaction binding the contract method 0x79e2cf97. +// +// Solidity: function updateGlobalExitRoot() returns() +func (_Legacy *LegacyTransactor) UpdateGlobalExitRoot(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Legacy.contract.Transact(opts, "updateGlobalExitRoot") +} + +// UpdateGlobalExitRoot is a paid mutator transaction binding the contract method 0x79e2cf97. +// +// Solidity: function updateGlobalExitRoot() returns() +func (_Legacy *LegacySession) UpdateGlobalExitRoot() (*types.Transaction, error) { + return _Legacy.Contract.UpdateGlobalExitRoot(&_Legacy.TransactOpts) +} + +// UpdateGlobalExitRoot is a paid mutator transaction binding the contract method 0x79e2cf97. +// +// Solidity: function updateGlobalExitRoot() returns() +func (_Legacy *LegacyTransactorSession) UpdateGlobalExitRoot() (*types.Transaction, error) { + return _Legacy.Contract.UpdateGlobalExitRoot(&_Legacy.TransactOpts) +} + +// LegacyBridgeEventIterator is returned from FilterBridgeEvent and is used to iterate over the raw logs and unpacked data for BridgeEvent events raised by the Legacy contract. +type LegacyBridgeEventIterator struct { + Event *LegacyBridgeEvent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *LegacyBridgeEventIterator) 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(LegacyBridgeEvent) + 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(LegacyBridgeEvent) + 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 *LegacyBridgeEventIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *LegacyBridgeEventIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// LegacyBridgeEvent represents a BridgeEvent event raised by the Legacy contract. +type LegacyBridgeEvent struct { + LeafType uint8 + OriginNetwork uint32 + OriginAddress common.Address + DestinationNetwork uint32 + DestinationAddress common.Address + Amount *big.Int + Metadata []byte + DepositCount uint32 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBridgeEvent is a free log retrieval operation binding the contract event 0x501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b. +// +// Solidity: event BridgeEvent(uint8 leafType, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata, uint32 depositCount) +func (_Legacy *LegacyFilterer) FilterBridgeEvent(opts *bind.FilterOpts) (*LegacyBridgeEventIterator, error) { + + logs, sub, err := _Legacy.contract.FilterLogs(opts, "BridgeEvent") + if err != nil { + return nil, err + } + return &LegacyBridgeEventIterator{contract: _Legacy.contract, event: "BridgeEvent", logs: logs, sub: sub}, nil +} + +// WatchBridgeEvent is a free log subscription operation binding the contract event 0x501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b. +// +// Solidity: event BridgeEvent(uint8 leafType, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata, uint32 depositCount) +func (_Legacy *LegacyFilterer) WatchBridgeEvent(opts *bind.WatchOpts, sink chan<- *LegacyBridgeEvent) (event.Subscription, error) { + + logs, sub, err := _Legacy.contract.WatchLogs(opts, "BridgeEvent") + 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(LegacyBridgeEvent) + if err := _Legacy.contract.UnpackLog(event, "BridgeEvent", 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 +} + +// ParseBridgeEvent is a log parse operation binding the contract event 0x501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b. +// +// Solidity: event BridgeEvent(uint8 leafType, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata, uint32 depositCount) +func (_Legacy *LegacyFilterer) ParseBridgeEvent(log types.Log) (*LegacyBridgeEvent, error) { + event := new(LegacyBridgeEvent) + if err := _Legacy.contract.UnpackLog(event, "BridgeEvent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// LegacyClaimEventIterator is returned from FilterClaimEvent and is used to iterate over the raw logs and unpacked data for ClaimEvent events raised by the Legacy contract. +type LegacyClaimEventIterator struct { + Event *LegacyClaimEvent // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *LegacyClaimEventIterator) 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(LegacyClaimEvent) + 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(LegacyClaimEvent) + 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 *LegacyClaimEventIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *LegacyClaimEventIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// LegacyClaimEvent represents a ClaimEvent event raised by the Legacy contract. +type LegacyClaimEvent struct { + Index uint32 + OriginNetwork uint32 + OriginAddress common.Address + DestinationAddress common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterClaimEvent is a free log retrieval operation binding the contract event 0x25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe27545983. +// +// Solidity: event ClaimEvent(uint32 index, uint32 originNetwork, address originAddress, address destinationAddress, uint256 amount) +func (_Legacy *LegacyFilterer) FilterClaimEvent(opts *bind.FilterOpts) (*LegacyClaimEventIterator, error) { + + logs, sub, err := _Legacy.contract.FilterLogs(opts, "ClaimEvent") + if err != nil { + return nil, err + } + return &LegacyClaimEventIterator{contract: _Legacy.contract, event: "ClaimEvent", logs: logs, sub: sub}, nil +} + +// WatchClaimEvent is a free log subscription operation binding the contract event 0x25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe27545983. +// +// Solidity: event ClaimEvent(uint32 index, uint32 originNetwork, address originAddress, address destinationAddress, uint256 amount) +func (_Legacy *LegacyFilterer) WatchClaimEvent(opts *bind.WatchOpts, sink chan<- *LegacyClaimEvent) (event.Subscription, error) { + + logs, sub, err := _Legacy.contract.WatchLogs(opts, "ClaimEvent") + 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(LegacyClaimEvent) + if err := _Legacy.contract.UnpackLog(event, "ClaimEvent", 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 +} + +// ParseClaimEvent is a log parse operation binding the contract event 0x25308c93ceeed162da955b3f7ce3e3f93606579e40fb92029faa9efe27545983. +// +// Solidity: event ClaimEvent(uint32 index, uint32 originNetwork, address originAddress, address destinationAddress, uint256 amount) +func (_Legacy *LegacyFilterer) ParseClaimEvent(log types.Log) (*LegacyClaimEvent, error) { + event := new(LegacyClaimEvent) + if err := _Legacy.contract.UnpackLog(event, "ClaimEvent", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// LegacyEmergencyStateActivatedIterator is returned from FilterEmergencyStateActivated and is used to iterate over the raw logs and unpacked data for EmergencyStateActivated events raised by the Legacy contract. +type LegacyEmergencyStateActivatedIterator struct { + Event *LegacyEmergencyStateActivated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *LegacyEmergencyStateActivatedIterator) 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(LegacyEmergencyStateActivated) + 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(LegacyEmergencyStateActivated) + 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 *LegacyEmergencyStateActivatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *LegacyEmergencyStateActivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// LegacyEmergencyStateActivated represents a EmergencyStateActivated event raised by the Legacy contract. +type LegacyEmergencyStateActivated struct { + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEmergencyStateActivated is a free log retrieval operation binding the contract event 0x2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a5497. +// +// Solidity: event EmergencyStateActivated() +func (_Legacy *LegacyFilterer) FilterEmergencyStateActivated(opts *bind.FilterOpts) (*LegacyEmergencyStateActivatedIterator, error) { + + logs, sub, err := _Legacy.contract.FilterLogs(opts, "EmergencyStateActivated") + if err != nil { + return nil, err + } + return &LegacyEmergencyStateActivatedIterator{contract: _Legacy.contract, event: "EmergencyStateActivated", logs: logs, sub: sub}, nil +} + +// WatchEmergencyStateActivated is a free log subscription operation binding the contract event 0x2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a5497. +// +// Solidity: event EmergencyStateActivated() +func (_Legacy *LegacyFilterer) WatchEmergencyStateActivated(opts *bind.WatchOpts, sink chan<- *LegacyEmergencyStateActivated) (event.Subscription, error) { + + logs, sub, err := _Legacy.contract.WatchLogs(opts, "EmergencyStateActivated") + 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(LegacyEmergencyStateActivated) + if err := _Legacy.contract.UnpackLog(event, "EmergencyStateActivated", 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 +} + +// ParseEmergencyStateActivated is a log parse operation binding the contract event 0x2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a5497. +// +// Solidity: event EmergencyStateActivated() +func (_Legacy *LegacyFilterer) ParseEmergencyStateActivated(log types.Log) (*LegacyEmergencyStateActivated, error) { + event := new(LegacyEmergencyStateActivated) + if err := _Legacy.contract.UnpackLog(event, "EmergencyStateActivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// LegacyEmergencyStateDeactivatedIterator is returned from FilterEmergencyStateDeactivated and is used to iterate over the raw logs and unpacked data for EmergencyStateDeactivated events raised by the Legacy contract. +type LegacyEmergencyStateDeactivatedIterator struct { + Event *LegacyEmergencyStateDeactivated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *LegacyEmergencyStateDeactivatedIterator) 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(LegacyEmergencyStateDeactivated) + 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(LegacyEmergencyStateDeactivated) + 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 *LegacyEmergencyStateDeactivatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *LegacyEmergencyStateDeactivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// LegacyEmergencyStateDeactivated represents a EmergencyStateDeactivated event raised by the Legacy contract. +type LegacyEmergencyStateDeactivated struct { + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEmergencyStateDeactivated is a free log retrieval operation binding the contract event 0x1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b3. +// +// Solidity: event EmergencyStateDeactivated() +func (_Legacy *LegacyFilterer) FilterEmergencyStateDeactivated(opts *bind.FilterOpts) (*LegacyEmergencyStateDeactivatedIterator, error) { + + logs, sub, err := _Legacy.contract.FilterLogs(opts, "EmergencyStateDeactivated") + if err != nil { + return nil, err + } + return &LegacyEmergencyStateDeactivatedIterator{contract: _Legacy.contract, event: "EmergencyStateDeactivated", logs: logs, sub: sub}, nil +} + +// WatchEmergencyStateDeactivated is a free log subscription operation binding the contract event 0x1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b3. +// +// Solidity: event EmergencyStateDeactivated() +func (_Legacy *LegacyFilterer) WatchEmergencyStateDeactivated(opts *bind.WatchOpts, sink chan<- *LegacyEmergencyStateDeactivated) (event.Subscription, error) { + + logs, sub, err := _Legacy.contract.WatchLogs(opts, "EmergencyStateDeactivated") + 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(LegacyEmergencyStateDeactivated) + if err := _Legacy.contract.UnpackLog(event, "EmergencyStateDeactivated", 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 +} + +// ParseEmergencyStateDeactivated is a log parse operation binding the contract event 0x1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b3. +// +// Solidity: event EmergencyStateDeactivated() +func (_Legacy *LegacyFilterer) ParseEmergencyStateDeactivated(log types.Log) (*LegacyEmergencyStateDeactivated, error) { + event := new(LegacyEmergencyStateDeactivated) + if err := _Legacy.contract.UnpackLog(event, "EmergencyStateDeactivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// LegacyInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Legacy contract. +type LegacyInitializedIterator struct { + Event *LegacyInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *LegacyInitializedIterator) 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(LegacyInitialized) + 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(LegacyInitialized) + 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 *LegacyInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *LegacyInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// LegacyInitialized represents a Initialized event raised by the Legacy contract. +type LegacyInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Legacy *LegacyFilterer) FilterInitialized(opts *bind.FilterOpts) (*LegacyInitializedIterator, error) { + + logs, sub, err := _Legacy.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &LegacyInitializedIterator{contract: _Legacy.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Legacy *LegacyFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *LegacyInitialized) (event.Subscription, error) { + + logs, sub, err := _Legacy.contract.WatchLogs(opts, "Initialized") + 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(LegacyInitialized) + if err := _Legacy.contract.UnpackLog(event, "Initialized", 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 +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Legacy *LegacyFilterer) ParseInitialized(log types.Log) (*LegacyInitialized, error) { + event := new(LegacyInitialized) + if err := _Legacy.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// LegacyNewWrappedTokenIterator is returned from FilterNewWrappedToken and is used to iterate over the raw logs and unpacked data for NewWrappedToken events raised by the Legacy contract. +type LegacyNewWrappedTokenIterator struct { + Event *LegacyNewWrappedToken // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *LegacyNewWrappedTokenIterator) 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(LegacyNewWrappedToken) + 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(LegacyNewWrappedToken) + 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 *LegacyNewWrappedTokenIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *LegacyNewWrappedTokenIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// LegacyNewWrappedToken represents a NewWrappedToken event raised by the Legacy contract. +type LegacyNewWrappedToken struct { + OriginNetwork uint32 + OriginTokenAddress common.Address + WrappedTokenAddress common.Address + Metadata []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNewWrappedToken is a free log retrieval operation binding the contract event 0x490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a39. +// +// Solidity: event NewWrappedToken(uint32 originNetwork, address originTokenAddress, address wrappedTokenAddress, bytes metadata) +func (_Legacy *LegacyFilterer) FilterNewWrappedToken(opts *bind.FilterOpts) (*LegacyNewWrappedTokenIterator, error) { + + logs, sub, err := _Legacy.contract.FilterLogs(opts, "NewWrappedToken") + if err != nil { + return nil, err + } + return &LegacyNewWrappedTokenIterator{contract: _Legacy.contract, event: "NewWrappedToken", logs: logs, sub: sub}, nil +} + +// WatchNewWrappedToken is a free log subscription operation binding the contract event 0x490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a39. +// +// Solidity: event NewWrappedToken(uint32 originNetwork, address originTokenAddress, address wrappedTokenAddress, bytes metadata) +func (_Legacy *LegacyFilterer) WatchNewWrappedToken(opts *bind.WatchOpts, sink chan<- *LegacyNewWrappedToken) (event.Subscription, error) { + + logs, sub, err := _Legacy.contract.WatchLogs(opts, "NewWrappedToken") + 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(LegacyNewWrappedToken) + if err := _Legacy.contract.UnpackLog(event, "NewWrappedToken", 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 +} + +// ParseNewWrappedToken is a log parse operation binding the contract event 0x490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a39. +// +// Solidity: event NewWrappedToken(uint32 originNetwork, address originTokenAddress, address wrappedTokenAddress, bytes metadata) +func (_Legacy *LegacyFilterer) ParseNewWrappedToken(log types.Log) (*LegacyNewWrappedToken, error) { + event := new(LegacyNewWrappedToken) + if err := _Legacy.contract.UnpackLog(event, "NewWrappedToken", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index 7bad8031..efa4264c 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -7,16 +7,18 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" ethrpc "github.com/ethereum/go-ethereum/rpc" + // note - this won't deal with the complexity of handling deposits prior to the ulxly "github.com/maticnetwork/polygon-cli/bindings/ulxly" "github.com/rs/zerolog/log" "github.com/spf13/cobra" ) type uLxLyArgs struct { - FromBlock *int64 - ToBlock *int64 + FromBlock *uint64 + ToBlock *uint64 RPCURL *string BridgeAddress *string + FilterSize *uint64 } var ulxlyInputArgs uLxLyArgs @@ -28,6 +30,7 @@ var ULxLyCmd = &cobra.Command{ Args: cobra.NoArgs, } +// polycli ulxly deposits --bridge-address 0x528e26b25a34a4A5d0dbDa1d57D318153d2ED582 --rpc-url https://sepolia-rpc.invalid --from-block 4880876 --to-block 6015235 --filter-size 9999 var DepositsCmd = &cobra.Command{ Use: "deposits", Short: "get a range of deposits", @@ -44,31 +47,43 @@ var DepositsCmd = &cobra.Command{ } defer rpc.Close() ec := ethclient.NewClient(rpc) - bridge, err := ulxly.NewUlxly(common.HexToAddress(*ulxlyInputArgs.BridgeAddress), ec) - if err != nil { - return err - } - fromBlock := uint64(*ulxlyInputArgs.FromBlock) - toBlock := uint64(*ulxlyInputArgs.ToBlock) - opts := bind.FilterOpts{ - Start: fromBlock, - End: &toBlock, - Context: ctx, - } - evtIterator, err := bridge.FilterBridgeEvent(&opts) + + bridgeV2, err := ulxly.NewUlxly(common.HexToAddress(*ulxlyInputArgs.BridgeAddress), ec) if err != nil { return err } - defer evtIterator.Close() - for evtIterator.Next() { - evt := evtIterator.Event - log.Info().Uint32("deposit", evt.DepositCount).Msg("Found Deposit") - jBytes, err := json.Marshal(evt) + fromBlock := *ulxlyInputArgs.FromBlock + toBlock := *ulxlyInputArgs.ToBlock + currentBlock := fromBlock + for currentBlock < toBlock { + endBlock := currentBlock + *ulxlyInputArgs.FilterSize + if endBlock > toBlock { + endBlock = toBlock + } + + opts := bind.FilterOpts{ + Start: currentBlock, + End: &endBlock, + Context: ctx, + } + evtV2Iterator, err := bridgeV2.FilterBridgeEvent(&opts) if err != nil { return err } - fmt.Println(string(jBytes)) + + for evtV2Iterator.Next() { + evt := evtV2Iterator.Event + log.Info().Uint32("deposit", evt.DepositCount).Uint64("block-number", evt.Raw.BlockNumber).Msg("Found ulxly Deposit") + jBytes, err := json.Marshal(evt) + if err != nil { + return err + } + fmt.Println(string(jBytes)) + } + evtV2Iterator.Close() + currentBlock = endBlock } + return nil }, } @@ -77,18 +92,18 @@ func checkDepositArgs(cmd *cobra.Command, args []string) error { if *ulxlyInputArgs.BridgeAddress == "" { return fmt.Errorf("please provide the bridge address") } + if *ulxlyInputArgs.FromBlock > *ulxlyInputArgs.ToBlock { + return fmt.Errorf("the from block should be less than the to block") + } return nil } func init() { ULxLyCmd.AddCommand(DepositsCmd) - // - When blockNr is -1 the chain pending header is returned. - // - When blockNr is -2 the chain latest header is returned. - // - When blockNr is -3 the chain finalized header is returned. - // - When blockNr is -4 the chain safe header is returned. - ulxlyInputArgs.FromBlock = DepositsCmd.PersistentFlags().Int64("from-block", 0, "The block height to start query at.") - ulxlyInputArgs.ToBlock = DepositsCmd.PersistentFlags().Int64("to-block", -2, "The block height to start query at.") + ulxlyInputArgs.FromBlock = DepositsCmd.PersistentFlags().Uint64("from-block", 0, "The block height to start query at.") + ulxlyInputArgs.ToBlock = DepositsCmd.PersistentFlags().Uint64("to-block", 0, "The block height to start query at.") ulxlyInputArgs.RPCURL = DepositsCmd.PersistentFlags().String("rpc-url", "http://127.0.0.1:8545", "The RPC to query for events") + ulxlyInputArgs.FilterSize = DepositsCmd.PersistentFlags().Uint64("filter-size", 1000, "The batch size for individual filter queries") ulxlyInputArgs.BridgeAddress = DepositsCmd.Flags().String("bridge-address", "", "The address of the lxly bridge") diff --git a/contracts/Makefile b/contracts/Makefile index 498e0d54..ba171add 100644 --- a/contracts/Makefile +++ b/contracts/Makefile @@ -51,5 +51,11 @@ gen-ulxly-go-bindings: abigen --abi ../bindings/ulxly/PolygonZkEVMBridgeV2.abi --bin ../bindings/ulxly/PolygonZkEVMBridgeV2.bin --pkg ulxly --type ulxly --out ../bindings/ulxly/PolygonZkEVMBridgeV2.go @echo "✅ ulxly/PolygonZkEVMBridgeV2.go generated" + cat ./out/PolygonZkEVMBridge.sol/PolygonZkEVMBridge.json | jq -r '.abi' > ../bindings/ulxly/PolygonZkEVMBridge.abi + cat ./out/PolygonZkEVMBridge.sol/PolygonZkEVMBridge.json | jq -r '.bytecode.object' > ../bindings/ulxly/PolygonZkEVMBridge.bin + abigen --abi ../bindings/ulxly/PolygonZkEVMBridge.abi --bin ../bindings/ulxly/PolygonZkEVMBridge.bin --pkg ulxly --type legacy --out ../bindings/ulxly/PolygonZkEVMBridge.go + @echo "✅ ulxly/PolygonZkEVMBridge.go generated" + + .PHONY: gen-go-bindings gen-go-bindings: build gen-funder-go-bindings gen-tester-go-bindings gen-tokens-go-bindings ## Generate go bindings. From 759af47e954f04e848b0f0c0797983b31fbc8df5 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Sun, 2 Jun 2024 09:43:11 -0400 Subject: [PATCH 03/46] feat: root calc --- cmd/ulxly/ulxly.go | 175 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index efa4264c..ad141b30 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -1,24 +1,48 @@ package ulxly import ( + "bufio" + "bytes" + "encoding/binary" "encoding/json" "fmt" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" ethrpc "github.com/ethereum/go-ethereum/rpc" + "golang.org/x/crypto/sha3" + "io" + "os" + "strings" + // note - this won't deal with the complexity of handling deposits prior to the ulxly "github.com/maticnetwork/polygon-cli/bindings/ulxly" "github.com/rs/zerolog/log" "github.com/spf13/cobra" ) +const ( + TreeDepth = 32 +) + type uLxLyArgs struct { FromBlock *uint64 ToBlock *uint64 RPCURL *string BridgeAddress *string FilterSize *uint64 + + InputFileName *string + NetworkID *uint64 +} + +type SMT struct { + Data map[string]string + Height uint8 + Count uint64 + Siblings [][TreeDepth]byte + Root [TreeDepth]byte } var ulxlyInputArgs uLxLyArgs @@ -87,7 +111,155 @@ var DepositsCmd = &cobra.Command{ return nil }, } +var ProofCmd = &cobra.Command{ + Use: "proof", + Short: "generate a merkle proof", + Long: "TODO", + Args: cobra.NoArgs, + PreRunE: checkProofArgs, + RunE: func(cmd *cobra.Command, args []string) error { + rawDepositData, err := getInputData(cmd, args) + if err != nil { + return err + } + readDeposits(rawDepositData) + return nil + }, +} + +func checkProofArgs(cmd *cobra.Command, args []string) error { + return nil +} +func getInputData(cmd *cobra.Command, args []string) ([]byte, error) { + if ulxlyInputArgs.InputFileName != nil && *ulxlyInputArgs.InputFileName != "" { + return os.ReadFile(*ulxlyInputArgs.InputFileName) + } + + if len(args) > 1 { + concat := strings.Join(args[1:], " ") + return []byte(concat), nil + } + + return io.ReadAll(os.Stdin) +} +func readDeposits(rawDeposits []byte) error { + buf := bytes.NewBuffer(rawDeposits) + scanner := bufio.NewScanner(buf) + smt := new(SMT) + smt.Init() + for scanner.Scan() { + evt := new(ulxly.UlxlyBridgeEvent) + err := json.Unmarshal(scanner.Bytes(), evt) + if err != nil { + return err + } + if evt.DestinationNetwork == uint32(*ulxlyInputArgs.NetworkID) { + smt.AddLeaf(evt) + log.Info(). + Uint64("block-number", evt.Raw.BlockNumber). + Uint32("deposit-count", evt.DepositCount). + Str("tx-hash", evt.Raw.TxHash.String()). + Str("root", smt.GetRoot().String()). + Msg("adding event to tree") + + } + } + return nil +} + +// This implementation looks good. We get this hash +// 0xf8c64768317c96c6c3c0f72b5a2cd3d03e831c200bf6bf0ab4d181877d59ddab +// for this deposit +// https://sepolia.etherscan.io/tx/0xf2003cf43a205bc777bc2d22fcb05b69ebb23464b39250d164cf9b09150b7833#eventlog +// And that seems to match a call to `getLeafValue` +func hashDeposit(deposit *ulxly.UlxlyBridgeEvent) [TreeDepth]byte { + var res [TreeDepth]byte + origNet := make([]byte, 4) //nolint:gomnd + binary.BigEndian.PutUint32(origNet, deposit.OriginNetwork) + destNet := make([]byte, 4) //nolint:gomnd + binary.BigEndian.PutUint32(destNet, deposit.DestinationNetwork) + var buf [TreeDepth]byte + metaHash := crypto.Keccak256Hash(deposit.Metadata) + copy(res[:], crypto.Keccak256Hash([]byte{deposit.LeafType}, origNet, deposit.OriginAddress.Bytes(), destNet, deposit.DestinationAddress[:], deposit.Amount.FillBytes(buf[:]), metaHash.Bytes()).Bytes()) + return res +} +func hash(data ...[TreeDepth]byte) [TreeDepth]byte { + var res [TreeDepth]byte + hash := sha3.NewLegacyKeccak256() + for _, d := range data { + hash.Write(d[:]) + } + copy(res[:], hash.Sum(nil)) + return res +} + +func (s *SMT) Init() { + s.Siblings = make([][TreeDepth]byte, 32) + for k := range s.Siblings { + s.Siblings[k] = [TreeDepth]byte{} + } + s.Height = TreeDepth + s.Data = nil // TODO pick a storage data structure +} + +// cast call --rpc-url https://eth-sepolia.g.alchemy.com/v2/demo --block 4880875 0xad1490c248c5d3cbae399fd529b79b42984277df 'lastMainnetExitRoot()(bytes32)' +// cast call --rpc-url https://eth-sepolia.g.alchemy.com/v2/demo --block 4880876 0xad1490c248c5d3cbae399fd529b79b42984277df 'lastMainnetExitRoot()(bytes32)' +// The first mainnet exit root for cardona is +// 0x112b077c64ed4a22dfb0ab3c2622d6ddbf3a5423afeb05878c2c21c4cb5e65da +func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { + current := hashDeposit(deposit) + log.Info().Str("leaf-hash", common.Bytes2Hex(current[:])).Msg("Leaf hash calculated") + isFilledSubTree := true // TODO ?!?! + + var leaves [][][]byte + for h := 0; h < TreeDepth; h++ { + if isBitSet(deposit.DepositCount+1, uint32(h)) { + child := current + parent := hash(s.Siblings[h], child) + current = parent + leaves = append(leaves, [][]byte{parent[:], s.Siblings[h][:], child[:]}) + } else { + if isFilledSubTree { + copy(s.Siblings[h][:], current[:]) + isFilledSubTree = false + } + child := current + parent := hash(child, [TreeDepth]byte{}) + current = parent + zeros := [TreeDepth]byte{} + leaves = append(leaves, [][]byte{parent[:], child[:], zeros[:]}) + } + } + s.Count += 1 + s.Root = current +} +func (s *SMT) GetRoot() common.Hash { + var node common.Hash + size := s.Count + var currentZeroHashHeight common.Hash + + zeros := [TreeDepth]byte{} + for height := 0; height < TreeDepth; height++ { + if ((size >> height) & 1) == 1 { + node = crypto.Keccak256Hash(s.Siblings[height][:], node.Bytes()) + } else { + node = crypto.Keccak256Hash(node.Bytes(), currentZeroHashHeight.Bytes()) + } + + currentZeroHashHeight = crypto.Keccak256Hash(zeros[:], zeros[:]) + } + return node +} + +// isBitSet checks if the bit at position h in number dc is set to 1 +func isBitSet(dc uint32, h uint32) bool { + mask := uint32(1) + for i := uint32(0); i < h; i++ { + mask *= 2 + } + return dc&mask > 0 +} func checkDepositArgs(cmd *cobra.Command, args []string) error { if *ulxlyInputArgs.BridgeAddress == "" { return fmt.Errorf("please provide the bridge address") @@ -100,11 +272,14 @@ func checkDepositArgs(cmd *cobra.Command, args []string) error { func init() { ULxLyCmd.AddCommand(DepositsCmd) + ULxLyCmd.AddCommand(ProofCmd) ulxlyInputArgs.FromBlock = DepositsCmd.PersistentFlags().Uint64("from-block", 0, "The block height to start query at.") ulxlyInputArgs.ToBlock = DepositsCmd.PersistentFlags().Uint64("to-block", 0, "The block height to start query at.") ulxlyInputArgs.RPCURL = DepositsCmd.PersistentFlags().String("rpc-url", "http://127.0.0.1:8545", "The RPC to query for events") ulxlyInputArgs.FilterSize = DepositsCmd.PersistentFlags().Uint64("filter-size", 1000, "The batch size for individual filter queries") ulxlyInputArgs.BridgeAddress = DepositsCmd.Flags().String("bridge-address", "", "The address of the lxly bridge") + ulxlyInputArgs.InputFileName = ProofCmd.PersistentFlags().String("file-name", "", "The filename with ndjson data of deposits") + ulxlyInputArgs.NetworkID = ProofCmd.PersistentFlags().Uint64("network-id", 1, "The network id to filter on") } From 8a3086c5ec022d78e9a785242c26e51eea83c341 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Sun, 2 Jun 2024 11:09:19 -0400 Subject: [PATCH 04/46] feat: initial roots match --- cmd/ulxly/ulxly.go | 71 ++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 47 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index ad141b30..48766d93 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -11,7 +11,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" ethrpc "github.com/ethereum/go-ethereum/rpc" - "golang.org/x/crypto/sha3" "io" "os" "strings" @@ -41,7 +40,7 @@ type SMT struct { Data map[string]string Height uint8 Count uint64 - Siblings [][TreeDepth]byte + Branches [][TreeDepth]byte Root [TreeDepth]byte } @@ -154,13 +153,14 @@ func readDeposits(rawDeposits []byte) error { return err } if evt.DestinationNetwork == uint32(*ulxlyInputArgs.NetworkID) { - smt.AddLeaf(evt) + log.Info(). Uint64("block-number", evt.Raw.BlockNumber). Uint32("deposit-count", evt.DepositCount). Str("tx-hash", evt.Raw.TxHash.String()). Str("root", smt.GetRoot().String()). Msg("adding event to tree") + smt.AddLeaf(evt) } } @@ -172,7 +172,7 @@ func readDeposits(rawDeposits []byte) error { // for this deposit // https://sepolia.etherscan.io/tx/0xf2003cf43a205bc777bc2d22fcb05b69ebb23464b39250d164cf9b09150b7833#eventlog // And that seems to match a call to `getLeafValue` -func hashDeposit(deposit *ulxly.UlxlyBridgeEvent) [TreeDepth]byte { +func hashDeposit(deposit *ulxly.UlxlyBridgeEvent) common.Hash { var res [TreeDepth]byte origNet := make([]byte, 4) //nolint:gomnd binary.BigEndian.PutUint32(origNet, deposit.OriginNetwork) @@ -183,20 +183,11 @@ func hashDeposit(deposit *ulxly.UlxlyBridgeEvent) [TreeDepth]byte { copy(res[:], crypto.Keccak256Hash([]byte{deposit.LeafType}, origNet, deposit.OriginAddress.Bytes(), destNet, deposit.DestinationAddress[:], deposit.Amount.FillBytes(buf[:]), metaHash.Bytes()).Bytes()) return res } -func hash(data ...[TreeDepth]byte) [TreeDepth]byte { - var res [TreeDepth]byte - hash := sha3.NewLegacyKeccak256() - for _, d := range data { - hash.Write(d[:]) - } - copy(res[:], hash.Sum(nil)) - return res -} func (s *SMT) Init() { - s.Siblings = make([][TreeDepth]byte, 32) - for k := range s.Siblings { - s.Siblings[k] = [TreeDepth]byte{} + s.Branches = make([][TreeDepth]byte, 32) + for k := range s.Branches { + s.Branches[k] = [TreeDepth]byte{} } s.Height = TreeDepth s.Data = nil // TODO pick a storage data structure @@ -207,55 +198,41 @@ func (s *SMT) Init() { // The first mainnet exit root for cardona is // 0x112b077c64ed4a22dfb0ab3c2622d6ddbf3a5423afeb05878c2c21c4cb5e65da func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { - current := hashDeposit(deposit) - log.Info().Str("leaf-hash", common.Bytes2Hex(current[:])).Msg("Leaf hash calculated") - isFilledSubTree := true // TODO ?!?! + leaf := hashDeposit(deposit) + log.Info().Str("leaf-hash", common.Bytes2Hex(leaf[:])).Msg("Leaf hash calculated") - var leaves [][][]byte - for h := 0; h < TreeDepth; h++ { - if isBitSet(deposit.DepositCount+1, uint32(h)) { - child := current - parent := hash(s.Siblings[h], child) - current = parent - leaves = append(leaves, [][]byte{parent[:], s.Siblings[h][:], child[:]}) - } else { - if isFilledSubTree { - copy(s.Siblings[h][:], current[:]) - isFilledSubTree = false - } - child := current - parent := hash(child, [TreeDepth]byte{}) - current = parent - zeros := [TreeDepth]byte{} - leaves = append(leaves, [][]byte{parent[:], child[:], zeros[:]}) + node := leaf + s.Count += 1 + size := s.Count + for height := uint64(0); height < TreeDepth; height += 1 { + if isBitSet(size, height) { + s.Branches[height] = node + break } + node = crypto.Keccak256Hash(s.Branches[height][:], node[:]) } - s.Count += 1 - s.Root = current + s.Root = s.GetRoot() } func (s *SMT) GetRoot() common.Hash { var node common.Hash size := s.Count - var currentZeroHashHeight common.Hash - - zeros := [TreeDepth]byte{} + currentZeroHashHeight := common.Hash{} for height := 0; height < TreeDepth; height++ { if ((size >> height) & 1) == 1 { - node = crypto.Keccak256Hash(s.Siblings[height][:], node.Bytes()) + node = crypto.Keccak256Hash(s.Branches[height][:], node.Bytes()) } else { node = crypto.Keccak256Hash(node.Bytes(), currentZeroHashHeight.Bytes()) } - - currentZeroHashHeight = crypto.Keccak256Hash(zeros[:], zeros[:]) + currentZeroHashHeight = crypto.Keccak256Hash(currentZeroHashHeight[:], currentZeroHashHeight[:]) } return node } // isBitSet checks if the bit at position h in number dc is set to 1 -func isBitSet(dc uint32, h uint32) bool { - mask := uint32(1) - for i := uint32(0); i < h; i++ { +func isBitSet(dc uint64, h uint64) bool { + mask := uint64(1) + for i := uint64(0); i < h; i++ { mask *= 2 } return dc&mask > 0 From f79191b7da6879b67e690c8371f2f39400c10704 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Sun, 2 Jun 2024 12:08:08 -0400 Subject: [PATCH 05/46] fix: working on cardona up to the head --- cmd/ulxly/ulxly.go | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index 48766d93..91af3907 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -54,6 +54,7 @@ var ULxLyCmd = &cobra.Command{ } // polycli ulxly deposits --bridge-address 0x528e26b25a34a4A5d0dbDa1d57D318153d2ED582 --rpc-url https://sepolia-rpc.invalid --from-block 4880876 --to-block 6015235 --filter-size 9999 +// polycli ulxly deposits --bridge-address 0x528e26b25a34a4A5d0dbDa1d57D318153d2ED582 --rpc-url https://sepolia-rpc.invalid --from-block 4880876 --to-block 6025854 --filter-size 999 > cardona-4880876-to-6025854.ndjson var DepositsCmd = &cobra.Command{ Use: "deposits", Short: "get a range of deposits", @@ -146,23 +147,32 @@ func readDeposits(rawDeposits []byte) error { scanner := bufio.NewScanner(buf) smt := new(SMT) smt.Init() + seenDeposit := make(map[uint32]common.Hash, 0) + lastDeposit := uint32(0) for scanner.Scan() { evt := new(ulxly.UlxlyBridgeEvent) err := json.Unmarshal(scanner.Bytes(), evt) if err != nil { return err } - if evt.DestinationNetwork == uint32(*ulxlyInputArgs.NetworkID) { - - log.Info(). - Uint64("block-number", evt.Raw.BlockNumber). - Uint32("deposit-count", evt.DepositCount). - Str("tx-hash", evt.Raw.TxHash.String()). - Str("root", smt.GetRoot().String()). - Msg("adding event to tree") - smt.AddLeaf(evt) - + if _, hasBeenSeen := seenDeposit[evt.DepositCount]; hasBeenSeen { + log.Warn().Uint32("deposit", evt.DepositCount).Str("tx-hash", evt.Raw.TxHash.String()).Msg("Skipping duplicate deposit") + continue } + seenDeposit[evt.DepositCount] = evt.Raw.TxHash + if lastDeposit+1 != evt.DepositCount && lastDeposit != 0 { + log.Error().Uint32("missing-deposit", lastDeposit+1).Uint32("current-deposit", evt.DepositCount).Msg("Missing deposit") + return fmt.Errorf("missing deposit: %d", lastDeposit+1) + } + lastDeposit = evt.DepositCount + smt.AddLeaf(evt) + log.Info(). + Uint64("block-number", evt.Raw.BlockNumber). + Uint32("deposit-count", evt.DepositCount). + Str("tx-hash", evt.Raw.TxHash.String()). + Str("root", smt.GetRoot().String()). + Msg("adding event to tree") + } return nil } From 1b70bf631526fea94a5f7543acbddcd1267d7eb6 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Sun, 2 Jun 2024 20:00:41 -0400 Subject: [PATCH 06/46] feat: proofs are partially there ... still some bugs --- cmd/ulxly/ulxly.go | 47 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index 91af3907..c3571e85 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -37,11 +37,12 @@ type uLxLyArgs struct { } type SMT struct { - Data map[string]string - Height uint8 - Count uint64 - Branches [][TreeDepth]byte - Root [TreeDepth]byte + Data map[uint32][]common.Hash + Height uint8 + Count uint64 + Branches [][TreeDepth]byte + Root [TreeDepth]byte + ZeroHashes [][TreeDepth]byte } var ulxlyInputArgs uLxLyArgs @@ -200,7 +201,8 @@ func (s *SMT) Init() { s.Branches[k] = [TreeDepth]byte{} } s.Height = TreeDepth - s.Data = nil // TODO pick a storage data structure + s.Data = make(map[uint32][]common.Hash, 0) + s.ZeroHashes = generateZeroHashes(TreeDepth) } // cast call --rpc-url https://eth-sepolia.g.alchemy.com/v2/demo --block 4880875 0xad1490c248c5d3cbae399fd529b79b42984277df 'lastMainnetExitRoot()(bytes32)' @@ -214,31 +216,58 @@ func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { node := leaf s.Count += 1 size := s.Count + maxHeight := 0 + for height := uint64(0); height < TreeDepth; height += 1 { + maxHeight = int(height) if isBitSet(size, height) { - s.Branches[height] = node + copy(s.Branches[height][:], node[:]) break } node = crypto.Keccak256Hash(s.Branches[height][:], node[:]) } s.Root = s.GetRoot() + proof := make([]common.Hash, TreeDepth) + zh := s.ZeroHashes + for k := 0; k < TreeDepth; k += 1 { + if k <= maxHeight { + proof[k] = s.Branches[k] + } else { + proof[k] = zh[k] + } + } + s.Data[deposit.DepositCount] = proof + // https://bridge-api.cardona.zkevm-rpc.com/merkle-proof?deposit_cnt=24357&net_id=0 + fmt.Println(proof) } + func (s *SMT) GetRoot() common.Hash { var node common.Hash size := s.Count - currentZeroHashHeight := common.Hash{} + var zeroHashes = s.ZeroHashes for height := 0; height < TreeDepth; height++ { + currentZeroHashHeight := zeroHashes[height] if ((size >> height) & 1) == 1 { node = crypto.Keccak256Hash(s.Branches[height][:], node.Bytes()) } else { - node = crypto.Keccak256Hash(node.Bytes(), currentZeroHashHeight.Bytes()) + node = crypto.Keccak256Hash(node.Bytes(), currentZeroHashHeight[:]) } currentZeroHashHeight = crypto.Keccak256Hash(currentZeroHashHeight[:], currentZeroHashHeight[:]) } return node } +// https://eth2book.info/capella/part2/deposits-withdrawals/contract/ +func generateZeroHashes(height uint8) [][TreeDepth]byte { + var zeroHashes = [][TreeDepth]byte{} + zeroHashes = append(zeroHashes, common.Hash{}) + for i := 1; i <= int(height); i++ { + zeroHashes = append(zeroHashes, crypto.Keccak256Hash(zeroHashes[i-1][:], zeroHashes[i-1][:])) + } + return zeroHashes +} + // isBitSet checks if the bit at position h in number dc is set to 1 func isBitSet(dc uint64, h uint64) bool { mask := uint64(1) From 7b146d377ca1a4d928b28354d4508731bfa59270 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Sun, 2 Jun 2024 21:31:03 -0400 Subject: [PATCH 07/46] fix: still some bugs --- cmd/ulxly/ulxly.go | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index c3571e85..57fffe0c 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -167,11 +167,13 @@ func readDeposits(rawDeposits []byte) error { } lastDeposit = evt.DepositCount smt.AddLeaf(evt) + rt, _ := smt.GetRoot() log.Info(). Uint64("block-number", evt.Raw.BlockNumber). Uint32("deposit-count", evt.DepositCount). + Uint64("mt-size", smt.Count). Str("tx-hash", evt.Raw.TxHash.String()). - Str("root", smt.GetRoot().String()). + Str("root", rt.String()). Msg("adding event to tree") } @@ -216,46 +218,46 @@ func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { node := leaf s.Count += 1 size := s.Count - maxHeight := 0 + // copy(node[:], s.ZeroHashes[0][:]) for height := uint64(0); height < TreeDepth; height += 1 { - maxHeight = int(height) if isBitSet(size, height) { copy(s.Branches[height][:], node[:]) break } node = crypto.Keccak256Hash(s.Branches[height][:], node[:]) } - s.Root = s.GetRoot() - proof := make([]common.Hash, TreeDepth) - zh := s.ZeroHashes - for k := 0; k < TreeDepth; k += 1 { - if k <= maxHeight { - proof[k] = s.Branches[k] - } else { - proof[k] = zh[k] - } - } - s.Data[deposit.DepositCount] = proof - // https://bridge-api.cardona.zkevm-rpc.com/merkle-proof?deposit_cnt=24357&net_id=0 - fmt.Println(proof) + var sibs [TreeDepth]common.Hash + s.Root, sibs = s.GetRoot() + + // fmt.Println(proof) + fmt.Println(sibs) } -func (s *SMT) GetRoot() common.Hash { +func (s *SMT) GetRoot() (common.Hash, [TreeDepth]common.Hash) { var node common.Hash size := s.Count var zeroHashes = s.ZeroHashes + siblings := [TreeDepth]common.Hash{} for height := 0; height < TreeDepth; height++ { currentZeroHashHeight := zeroHashes[height] + left := crypto.Keccak256Hash(s.Branches[height][:], node.Bytes()) + right := crypto.Keccak256Hash(node.Bytes(), currentZeroHashHeight[:]) + log.Debug(). + Str("sib-1", node.String()). + Str("sib-2", common.Hash(s.Branches[height]).String()). + Str("sib-3", common.Hash(currentZeroHashHeight).String()).Msg("tree values") + if ((size >> height) & 1) == 1 { - node = crypto.Keccak256Hash(s.Branches[height][:], node.Bytes()) + copy(siblings[height][:], s.Branches[height][:]) + node = left } else { - node = crypto.Keccak256Hash(node.Bytes(), currentZeroHashHeight[:]) + copy(siblings[height][:], currentZeroHashHeight[:]) + node = right } - currentZeroHashHeight = crypto.Keccak256Hash(currentZeroHashHeight[:], currentZeroHashHeight[:]) } - return node + return node, siblings } // https://eth2book.info/capella/part2/deposits-withdrawals/contract/ From 4a193125ab3deb2ffb007afd58934d27777463e8 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Mon, 3 Jun 2024 12:35:00 -0400 Subject: [PATCH 08/46] feat: storing all branch sets --- cmd/ulxly/ulxly.go | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index 57fffe0c..fe932398 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -40,7 +40,7 @@ type SMT struct { Data map[uint32][]common.Hash Height uint8 Count uint64 - Branches [][TreeDepth]byte + Branches map[uint32][][TreeDepth]byte Root [TreeDepth]byte ZeroHashes [][TreeDepth]byte } @@ -167,13 +167,12 @@ func readDeposits(rawDeposits []byte) error { } lastDeposit = evt.DepositCount smt.AddLeaf(evt) - rt, _ := smt.GetRoot() log.Info(). Uint64("block-number", evt.Raw.BlockNumber). Uint32("deposit-count", evt.DepositCount). Uint64("mt-size", smt.Count). Str("tx-hash", evt.Raw.TxHash.String()). - Str("root", rt.String()). + Str("root", common.Hash(smt.Root).String()). Msg("adding event to tree") } @@ -198,10 +197,7 @@ func hashDeposit(deposit *ulxly.UlxlyBridgeEvent) common.Hash { } func (s *SMT) Init() { - s.Branches = make([][TreeDepth]byte, 32) - for k := range s.Branches { - s.Branches[k] = [TreeDepth]byte{} - } + s.Branches = make(map[uint32][][TreeDepth]byte) s.Height = TreeDepth s.Data = make(map[uint32][]common.Hash, 0) s.ZeroHashes = generateZeroHashes(TreeDepth) @@ -219,45 +215,44 @@ func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { s.Count += 1 size := s.Count + branches := make([][TreeDepth]byte, TreeDepth) + copy(branches, s.Branches[deposit.DepositCount-1]) // copy(node[:], s.ZeroHashes[0][:]) for height := uint64(0); height < TreeDepth; height += 1 { if isBitSet(size, height) { - copy(s.Branches[height][:], node[:]) + copy(branches[height][:], node[:]) break } - node = crypto.Keccak256Hash(s.Branches[height][:], node[:]) + node = crypto.Keccak256Hash(branches[height][:], node[:]) } - var sibs [TreeDepth]common.Hash - s.Root, sibs = s.GetRoot() - - // fmt.Println(proof) - fmt.Println(sibs) + s.Branches[deposit.DepositCount] = branches + s.Root = s.GetRoot(deposit.DepositCount) } -func (s *SMT) GetRoot() (common.Hash, [TreeDepth]common.Hash) { +func (s *SMT) GetRoot(depositNum uint32) common.Hash { var node common.Hash size := s.Count var zeroHashes = s.ZeroHashes - siblings := [TreeDepth]common.Hash{} + // siblings := [TreeDepth]common.Hash{} for height := 0; height < TreeDepth; height++ { currentZeroHashHeight := zeroHashes[height] - left := crypto.Keccak256Hash(s.Branches[height][:], node.Bytes()) + left := crypto.Keccak256Hash(s.Branches[depositNum][height][:], node.Bytes()) right := crypto.Keccak256Hash(node.Bytes(), currentZeroHashHeight[:]) log.Debug(). Str("sib-1", node.String()). - Str("sib-2", common.Hash(s.Branches[height]).String()). + Str("sib-2", common.Hash(s.Branches[depositNum][height]).String()). Str("sib-3", common.Hash(currentZeroHashHeight).String()).Msg("tree values") if ((size >> height) & 1) == 1 { - copy(siblings[height][:], s.Branches[height][:]) + // copy(siblings[height][:], s.Branches[height][:]) node = left } else { - copy(siblings[height][:], currentZeroHashHeight[:]) + // copy(siblings[height][:], currentZeroHashHeight[:]) node = right } } - return node, siblings + return node } // https://eth2book.info/capella/part2/deposits-withdrawals/contract/ From 9e60527d21b85ff08b527f1070c73eb5ee7b600c Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Tue, 4 Jun 2024 13:59:34 -0400 Subject: [PATCH 09/46] wip: all of the roots look good, but prior proofs still not --- cmd/ulxly/ulxly.go | 123 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 108 insertions(+), 15 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index fe932398..66f089d7 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -33,7 +33,7 @@ type uLxLyArgs struct { FilterSize *uint64 InputFileName *string - NetworkID *uint64 + DepositNum *uint32 } type SMT struct { @@ -43,6 +43,12 @@ type SMT struct { Branches map[uint32][][TreeDepth]byte Root [TreeDepth]byte ZeroHashes [][TreeDepth]byte + Proofs map[uint32]Proof +} +type Proof struct { + Siblings [TreeDepth]common.Hash + Root common.Hash + DepositCount uint32 } var ulxlyInputArgs uLxLyArgs @@ -170,15 +176,28 @@ func readDeposits(rawDeposits []byte) error { log.Info(). Uint64("block-number", evt.Raw.BlockNumber). Uint32("deposit-count", evt.DepositCount). - Uint64("mt-size", smt.Count). Str("tx-hash", evt.Raw.TxHash.String()). Str("root", common.Hash(smt.Root).String()). Msg("adding event to tree") } + + p := smt.Proofs[*ulxlyInputArgs.DepositNum] + + fmt.Println(p.String()) return nil } +func (p *Proof) String() string { + jsonBytes, err := json.Marshal(p) + if err != nil { + log.Error().Err(err).Msg("error marshalling proof to json") + return "" + } + return string(jsonBytes) + +} + // This implementation looks good. We get this hash // 0xf8c64768317c96c6c3c0f72b5a2cd3d03e831c200bf6bf0ab4d181877d59ddab // for this deposit @@ -201,6 +220,7 @@ func (s *SMT) Init() { s.Height = TreeDepth s.Data = make(map[uint32][]common.Hash, 0) s.ZeroHashes = generateZeroHashes(TreeDepth) + s.Proofs = make(map[uint32]Proof) } // cast call --rpc-url https://eth-sepolia.g.alchemy.com/v2/demo --block 4880875 0xad1490c248c5d3cbae399fd529b79b42984277df 'lastMainnetExitRoot()(bytes32)' @@ -212,12 +232,15 @@ func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { log.Info().Str("leaf-hash", common.Bytes2Hex(leaf[:])).Msg("Leaf hash calculated") node := leaf - s.Count += 1 + s.Count = uint64(deposit.DepositCount) + 1 size := s.Count - branches := make([][TreeDepth]byte, TreeDepth) - copy(branches, s.Branches[deposit.DepositCount-1]) - // copy(node[:], s.ZeroHashes[0][:]) + if deposit.DepositCount == 0 { + branches = generateZeroHashes(TreeDepth) + } else { + copy(branches, s.Branches[deposit.DepositCount-1]) + } + for height := uint64(0); height < TreeDepth; height += 1 { if isBitSet(size, height) { copy(branches[height][:], node[:]) @@ -234,27 +257,98 @@ func (s *SMT) GetRoot(depositNum uint32) common.Hash { size := s.Count var zeroHashes = s.ZeroHashes - // siblings := [TreeDepth]common.Hash{} + siblings := [TreeDepth]common.Hash{} for height := 0; height < TreeDepth; height++ { currentZeroHashHeight := zeroHashes[height] left := crypto.Keccak256Hash(s.Branches[depositNum][height][:], node.Bytes()) right := crypto.Keccak256Hash(node.Bytes(), currentZeroHashHeight[:]) - log.Debug(). - Str("sib-1", node.String()). - Str("sib-2", common.Hash(s.Branches[depositNum][height]).String()). - Str("sib-3", common.Hash(currentZeroHashHeight).String()).Msg("tree values") + if depositNum == 24391 { + log.Debug(). + Int("height", height). + Str("sib-1", node.String()). + Str("sib-2", common.Hash(s.Branches[depositNum][height]).String()). + Str("sib-3", common.Hash(currentZeroHashHeight).String()). + Str("left", left.String()). + Str("right", right.String()). + Msg("tree values") + } if ((size >> height) & 1) == 1 { - // copy(siblings[height][:], s.Branches[height][:]) + copy(siblings[height][:], currentZeroHashHeight[:]) node = left } else { - // copy(siblings[height][:], currentZeroHashHeight[:]) + copy(siblings[height][:], s.Branches[depositNum][height][:]) node = right } } + if depositNum^1 == 1 { + copy(siblings[0][:], zeroHashes[0][:]) + } else { + copy(siblings[0][:], s.Branches[depositNum-1][0][:]) + } + + s.Proofs[depositNum] = Proof{ + Siblings: siblings, + Root: node, + DepositCount: depositNum, + } + log.Info().Str("inner-root", s.Proofs[depositNum].Root.String()).Str("root", node.String()).Msg("root Check") return node } +// GetProof will try to generate the paired hashes for each level of the tree for a given deposit +func (s *SMT) GetProof(depositNum uint32) ([][TreeDepth]byte, error) { + // it's possible to call this with a deposit that doesn't exist. In theory this should be fine, but it doesn't really fit the intent of the code here + if uint64(depositNum) > s.Count { + return nil, fmt.Errorf("deposit number %d is greater than the count %d of leaves", depositNum, s.Count) + } + + // At the bottom of the path, we need to find the deposit that is paired with the despot that we're checking. We should be able to flip the last bit and get the deposit number + siblingDepositNum := depositNum ^ 1 + + var siblingLeaf [TreeDepth]byte + if _, hasKey := s.Branches[siblingDepositNum]; !hasKey || siblingDepositNum > depositNum { + siblingLeaf = [TreeDepth]byte{} + } else { + siblingLeaf = s.Branches[siblingDepositNum][0] + } + siblings := [TreeDepth][TreeDepth]byte{} + siblings[0] = siblingLeaf + siblingMask := uint32(1) + // Iterate through the levels of the tree + for height := 1; height < TreeDepth; height += 1 { + // At each height, we're going to flip a bit in the deposit number in order to find the complimentary node for the given height + siblingMask = uint32(siblingMask<<1) + 1 + flipMask := uint32(1 << height) + currentSiblingDeposit := (depositNum | siblingMask) ^ flipMask + + // we'll get the branches from the particular deposit that we're interested in + b, hasKey := s.Branches[currentSiblingDeposit] + if !hasKey || isEmpty(b[height]) || currentSiblingDeposit > depositNum { + b = generateZeroHashes(TreeDepth) + } + siblings[height] = b[height] + log.Info(). + Int("height", height). + Uint32("current-sibling-num", currentSiblingDeposit). + Str("current-sibling", fmt.Sprintf("%b", currentSiblingDeposit)). + Str("current-mask", fmt.Sprintf("%b", siblingMask)). + Str("sib", common.Hash(b[height]).String()). + Msg("Getting Deposit") + + } + return siblings[:], nil +} + +func isEmpty(h [TreeDepth]byte) bool { + for i := 0; i < TreeDepth; i = i + 1 { + if h[i] != 0 { + return false + } + } + return true +} + // https://eth2book.info/capella/part2/deposits-withdrawals/contract/ func generateZeroHashes(height uint8) [][TreeDepth]byte { var zeroHashes = [][TreeDepth]byte{} @@ -293,6 +387,5 @@ func init() { ulxlyInputArgs.BridgeAddress = DepositsCmd.Flags().String("bridge-address", "", "The address of the lxly bridge") ulxlyInputArgs.InputFileName = ProofCmd.PersistentFlags().String("file-name", "", "The filename with ndjson data of deposits") - ulxlyInputArgs.NetworkID = ProofCmd.PersistentFlags().Uint64("network-id", 1, "The network id to filter on") - + ulxlyInputArgs.DepositNum = ProofCmd.PersistentFlags().Uint32("deposit-number", 0, "The deposit that we would like to prove") } From 0c005a2f8a88302dcc7690c0fe86071f9d3acf41 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Tue, 4 Jun 2024 14:14:59 -0400 Subject: [PATCH 10/46] fix: even numbers work? --- cmd/ulxly/ulxly.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index 66f089d7..f201e4ec 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -263,7 +263,7 @@ func (s *SMT) GetRoot(depositNum uint32) common.Hash { left := crypto.Keccak256Hash(s.Branches[depositNum][height][:], node.Bytes()) right := crypto.Keccak256Hash(node.Bytes(), currentZeroHashHeight[:]) if depositNum == 24391 { - log.Debug(). + log.Info(). Int("height", height). Str("sib-1", node.String()). Str("sib-2", common.Hash(s.Branches[depositNum][height]).String()). @@ -274,17 +274,17 @@ func (s *SMT) GetRoot(depositNum uint32) common.Hash { } if ((size >> height) & 1) == 1 { - copy(siblings[height][:], currentZeroHashHeight[:]) + copy(siblings[height][:], s.Branches[depositNum][height][:]) node = left } else { - copy(siblings[height][:], s.Branches[depositNum][height][:]) + copy(siblings[height][:], currentZeroHashHeight[:]) node = right } } - if depositNum^1 == 1 { - copy(siblings[0][:], zeroHashes[0][:]) - } else { + if depositNum&1 == 1 { copy(siblings[0][:], s.Branches[depositNum-1][0][:]) + } else { + copy(siblings[0][:], zeroHashes[0][:]) } s.Proofs[depositNum] = Proof{ From 5d5f6189ce0ab1e8c060f6b8a1163aa778ee20fd Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Tue, 4 Jun 2024 15:09:22 -0400 Subject: [PATCH 11/46] feat: adding proof check --- cmd/ulxly/ulxly.go | 73 +++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 43 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index f201e4ec..afb2a3b6 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -49,6 +49,7 @@ type Proof struct { Siblings [TreeDepth]common.Hash Root common.Hash DepositCount uint32 + LeafHash common.Hash } var ulxlyInputArgs uLxLyArgs @@ -229,7 +230,7 @@ func (s *SMT) Init() { // 0x112b077c64ed4a22dfb0ab3c2622d6ddbf3a5423afeb05878c2c21c4cb5e65da func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { leaf := hashDeposit(deposit) - log.Info().Str("leaf-hash", common.Bytes2Hex(leaf[:])).Msg("Leaf hash calculated") + log.Debug().Str("leaf-hash", common.Bytes2Hex(leaf[:])).Msg("Leaf hash calculated") node := leaf s.Count = uint64(deposit.DepositCount) + 1 @@ -282,64 +283,50 @@ func (s *SMT) GetRoot(depositNum uint32) common.Hash { } } if depositNum&1 == 1 { + // If we're odd, then the first sibling, should be the previous leafhash copy(siblings[0][:], s.Branches[depositNum-1][0][:]) } else { + // If we're even, the first sibling should be empty. copy(siblings[0][:], zeroHashes[0][:]) } - s.Proofs[depositNum] = Proof{ + p := &Proof{ Siblings: siblings, Root: node, DepositCount: depositNum, + LeafHash: s.Branches[depositNum][0], } - log.Info().Str("inner-root", s.Proofs[depositNum].Root.String()).Str("root", node.String()).Msg("root Check") + + err := p.Check() + if err != nil { + log.Error().Err(err).Msg("failed to validate proof") + } + s.Proofs[depositNum] = *p return node } -// GetProof will try to generate the paired hashes for each level of the tree for a given deposit -func (s *SMT) GetProof(depositNum uint32) ([][TreeDepth]byte, error) { - // it's possible to call this with a deposit that doesn't exist. In theory this should be fine, but it doesn't really fit the intent of the code here - if uint64(depositNum) > s.Count { - return nil, fmt.Errorf("deposit number %d is greater than the count %d of leaves", depositNum, s.Count) +func (p *Proof) Check() error { + node := p.LeafHash + index := p.DepositCount + for height := 0; height < TreeDepth; height++ { + if ((index >> height) & 1) == 1 { + node = crypto.Keccak256Hash(p.Siblings[height][:], node[:]) + } else { + node = crypto.Keccak256Hash(node[:], p.Siblings[height][:]) + } } - - // At the bottom of the path, we need to find the deposit that is paired with the despot that we're checking. We should be able to flip the last bit and get the deposit number - siblingDepositNum := depositNum ^ 1 - - var siblingLeaf [TreeDepth]byte - if _, hasKey := s.Branches[siblingDepositNum]; !hasKey || siblingDepositNum > depositNum { - siblingLeaf = [TreeDepth]byte{} - } else { - siblingLeaf = s.Branches[siblingDepositNum][0] + isProofValid := p.Root.Cmp(node) == 0 + log.Info(). + Bool("is-proof-valid", isProofValid). + Uint32("deposit-count", p.DepositCount). + Str("expected-root", p.Root.String()). + Str("checked-root", node.String()).Msg("checking proof") + if !isProofValid { + return fmt.Errorf("invalid proof") } - siblings := [TreeDepth][TreeDepth]byte{} - siblings[0] = siblingLeaf - siblingMask := uint32(1) - // Iterate through the levels of the tree - for height := 1; height < TreeDepth; height += 1 { - // At each height, we're going to flip a bit in the deposit number in order to find the complimentary node for the given height - siblingMask = uint32(siblingMask<<1) + 1 - flipMask := uint32(1 << height) - currentSiblingDeposit := (depositNum | siblingMask) ^ flipMask - - // we'll get the branches from the particular deposit that we're interested in - b, hasKey := s.Branches[currentSiblingDeposit] - if !hasKey || isEmpty(b[height]) || currentSiblingDeposit > depositNum { - b = generateZeroHashes(TreeDepth) - } - siblings[height] = b[height] - log.Info(). - Int("height", height). - Uint32("current-sibling-num", currentSiblingDeposit). - Str("current-sibling", fmt.Sprintf("%b", currentSiblingDeposit)). - Str("current-mask", fmt.Sprintf("%b", siblingMask)). - Str("sib", common.Hash(b[height]).String()). - Msg("Getting Deposit") - } - return siblings[:], nil + return nil } - func isEmpty(h [TreeDepth]byte) bool { for i := 0; i < TreeDepth; i = i + 1 { if h[i] != 0 { From 32ac5b43ef7060bdb9a0bb27102dc5cf265e00ea Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Tue, 4 Jun 2024 15:58:58 -0400 Subject: [PATCH 12/46] refactor: dropping isBitSet since it is more confusing --- cmd/ulxly/ulxly.go | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index afb2a3b6..57e5c8d1 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -243,7 +243,7 @@ func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { } for height := uint64(0); height < TreeDepth; height += 1 { - if isBitSet(size, height) { + if ((size >> height) & 1) == 1 { copy(branches[height][:], node[:]) break } @@ -345,15 +345,6 @@ func generateZeroHashes(height uint8) [][TreeDepth]byte { } return zeroHashes } - -// isBitSet checks if the bit at position h in number dc is set to 1 -func isBitSet(dc uint64, h uint64) bool { - mask := uint64(1) - for i := uint64(0); i < h; i++ { - mask *= 2 - } - return dc&mask > 0 -} func checkDepositArgs(cmd *cobra.Command, args []string) error { if *ulxlyInputArgs.BridgeAddress == "" { return fmt.Errorf("please provide the bridge address") From 44771232310ad755dd2e7a55506bbd57359db7ba Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Tue, 4 Jun 2024 16:00:33 -0400 Subject: [PATCH 13/46] refactor: removing unnecessary count --- cmd/ulxly/ulxly.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index 57e5c8d1..b8029e16 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -39,7 +39,6 @@ type uLxLyArgs struct { type SMT struct { Data map[uint32][]common.Hash Height uint8 - Count uint64 Branches map[uint32][][TreeDepth]byte Root [TreeDepth]byte ZeroHashes [][TreeDepth]byte @@ -233,8 +232,7 @@ func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { log.Debug().Str("leaf-hash", common.Bytes2Hex(leaf[:])).Msg("Leaf hash calculated") node := leaf - s.Count = uint64(deposit.DepositCount) + 1 - size := s.Count + size := uint64(deposit.DepositCount) + 1 branches := make([][TreeDepth]byte, TreeDepth) if deposit.DepositCount == 0 { branches = generateZeroHashes(TreeDepth) @@ -255,7 +253,7 @@ func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { func (s *SMT) GetRoot(depositNum uint32) common.Hash { var node common.Hash - size := s.Count + size := depositNum + 1 var zeroHashes = s.ZeroHashes siblings := [TreeDepth]common.Hash{} @@ -264,7 +262,7 @@ func (s *SMT) GetRoot(depositNum uint32) common.Hash { left := crypto.Keccak256Hash(s.Branches[depositNum][height][:], node.Bytes()) right := crypto.Keccak256Hash(node.Bytes(), currentZeroHashHeight[:]) if depositNum == 24391 { - log.Info(). + log.Debug(). Int("height", height). Str("sib-1", node.String()). Str("sib-2", common.Hash(s.Branches[depositNum][height]).String()). From 36f5189a76b6b4c0157e9379198da9097326d4ae Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Tue, 4 Jun 2024 17:55:00 -0400 Subject: [PATCH 14/46] fix: simplifcation --- cmd/ulxly/ulxly.go | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index b8029e16..f6be4a42 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -252,42 +252,29 @@ func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { } func (s *SMT) GetRoot(depositNum uint32) common.Hash { - var node common.Hash + var node common.Hash = s.Branches[depositNum][0] size := depositNum + 1 var zeroHashes = s.ZeroHashes + prevDepositNum := depositNum - 1 + if depositNum == 0 { + prevDepositNum = 0 + } + siblings := [TreeDepth]common.Hash{} for height := 0; height < TreeDepth; height++ { currentZeroHashHeight := zeroHashes[height] - left := crypto.Keccak256Hash(s.Branches[depositNum][height][:], node.Bytes()) + left := crypto.Keccak256Hash(s.Branches[prevDepositNum][height][:], node.Bytes()) right := crypto.Keccak256Hash(node.Bytes(), currentZeroHashHeight[:]) - if depositNum == 24391 { - log.Debug(). - Int("height", height). - Str("sib-1", node.String()). - Str("sib-2", common.Hash(s.Branches[depositNum][height]).String()). - Str("sib-3", common.Hash(currentZeroHashHeight).String()). - Str("left", left.String()). - Str("right", right.String()). - Msg("tree values") - } if ((size >> height) & 1) == 1 { - copy(siblings[height][:], s.Branches[depositNum][height][:]) + copy(siblings[height][:], s.Branches[prevDepositNum][height][:]) node = left } else { copy(siblings[height][:], currentZeroHashHeight[:]) node = right } } - if depositNum&1 == 1 { - // If we're odd, then the first sibling, should be the previous leafhash - copy(siblings[0][:], s.Branches[depositNum-1][0][:]) - } else { - // If we're even, the first sibling should be empty. - copy(siblings[0][:], zeroHashes[0][:]) - } - p := &Proof{ Siblings: siblings, Root: node, From 646ac3e4c48c4dd70827f1613ef90360b6046838 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Tue, 4 Jun 2024 20:50:22 -0400 Subject: [PATCH 15/46] fix: proof logic --- cmd/ulxly/ulxly.go | 98 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 20 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index f6be4a42..45645a34 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -37,9 +37,9 @@ type uLxLyArgs struct { } type SMT struct { - Data map[uint32][]common.Hash Height uint8 Branches map[uint32][][TreeDepth]byte + Leaves map[uint32]common.Hash Root [TreeDepth]byte ZeroHashes [][TreeDepth]byte Proofs map[uint32]Proof @@ -182,9 +182,10 @@ func readDeposits(rawDeposits []byte) error { } - p := smt.Proofs[*ulxlyInputArgs.DepositNum] + // p := smt.Proofs[*ulxlyInputArgs.DepositNum] + smt.GetProof(*ulxlyInputArgs.DepositNum) - fmt.Println(p.String()) + // fmt.Println(p.String()) return nil } @@ -218,7 +219,7 @@ func hashDeposit(deposit *ulxly.UlxlyBridgeEvent) common.Hash { func (s *SMT) Init() { s.Branches = make(map[uint32][][TreeDepth]byte) s.Height = TreeDepth - s.Data = make(map[uint32][]common.Hash, 0) + s.Leaves = make(map[uint32]common.Hash) s.ZeroHashes = generateZeroHashes(TreeDepth) s.Proofs = make(map[uint32]Proof) } @@ -230,12 +231,16 @@ func (s *SMT) Init() { func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { leaf := hashDeposit(deposit) log.Debug().Str("leaf-hash", common.Bytes2Hex(leaf[:])).Msg("Leaf hash calculated") + // just keep a copy of the leaf indexed by deposit count for now + s.Leaves[deposit.DepositCount] = leaf node := leaf size := uint64(deposit.DepositCount) + 1 + + // copy the previous set of branches as a starting point. We're going to make copies of the branches at each deposit branches := make([][TreeDepth]byte, TreeDepth) if deposit.DepositCount == 0 { - branches = generateZeroHashes(TreeDepth) + branches = generateEmptyHashes(TreeDepth) } else { copy(branches, s.Branches[deposit.DepositCount-1]) } @@ -252,32 +257,54 @@ func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { } func (s *SMT) GetRoot(depositNum uint32) common.Hash { - var node common.Hash = s.Branches[depositNum][0] + node := common.Hash{} size := depositNum + 1 - var zeroHashes = s.ZeroHashes + currentZeroHashHeight := common.Hash{} + + for height := 0; height < TreeDepth; height++ { + if ((size >> height) & 1) == 1 { + // node = keccak256(abi.encodePacked(_branch[height], node)); + node = crypto.Keccak256Hash(s.Branches[depositNum][height][:], node.Bytes()) - prevDepositNum := depositNum - 1 - if depositNum == 0 { - prevDepositNum = 0 + } else { + // node = keccak256(abi.encodePacked(node, currentZeroHashHeight)); + node = crypto.Keccak256Hash(node.Bytes(), currentZeroHashHeight.Bytes()) + } + currentZeroHashHeight = crypto.Keccak256Hash(currentZeroHashHeight.Bytes(), currentZeroHashHeight.Bytes()) } + return node +} + +func (s *SMT) GetProof(depositNum uint32) Proof { + node := common.Hash{} + sibling := common.Hash{} + size := depositNum + 1 + currentZeroHashHeight := common.Hash{} - siblings := [TreeDepth]common.Hash{} + siblings := [32]common.Hash{} for height := 0; height < TreeDepth; height++ { - currentZeroHashHeight := zeroHashes[height] - left := crypto.Keccak256Hash(s.Branches[prevDepositNum][height][:], node.Bytes()) - right := crypto.Keccak256Hash(node.Bytes(), currentZeroHashHeight[:]) + siblingDepositNum := getSiblingDepositNumber(depositNum, uint32(height)) + if _, hasKey := s.Branches[siblingDepositNum]; hasKey { + sibling = s.Branches[siblingDepositNum][height] + } else { + sibling = currentZeroHashHeight + } + + log.Info().Str("sibling", sibling.String()).Msg("Proof Inputs") + siblings[height] = sibling if ((size >> height) & 1) == 1 { - copy(siblings[height][:], s.Branches[prevDepositNum][height][:]) - node = left + // node = keccak256(abi.encodePacked(_branch[height], node)); + node = crypto.Keccak256Hash(sibling.Bytes(), node.Bytes()) } else { - copy(siblings[height][:], currentZeroHashHeight[:]) - node = right + // node = keccak256(abi.encodePacked(node, currentZeroHashHeight)); + node = crypto.Keccak256Hash(node.Bytes(), sibling.Bytes()) } + currentZeroHashHeight = crypto.Keccak256Hash(currentZeroHashHeight.Bytes(), currentZeroHashHeight.Bytes()) } p := &Proof{ Siblings: siblings, - Root: node, + Root: s.Root, DepositCount: depositNum, LeafHash: s.Branches[depositNum][0], } @@ -287,7 +314,29 @@ func (s *SMT) GetRoot(depositNum uint32) common.Hash { log.Error().Err(err).Msg("failed to validate proof") } s.Proofs[depositNum] = *p - return node + return *p +} + +// getSiblingDepositNumber returns the sibling number of a given number at a specified level in an incremental Merkle tree. +// +// In an incremental Merkle tree, each node has a sibling node at each level of the tree. +// The sibling node can be determined by flipping the bit at the current level and setting all bits to the right of the current level to 1. +// This function calculates the sibling number based on the deposit number and the specified level. +// +// Parameters: +// - depositNumber: the original number for which the sibling is to be found. +// - level: the level in the Merkle tree at which to find the sibling. +// +// The logic works as follows: +// 1. `1 << level` creates a binary number with a single 1 bit at the position corresponding to the level. +// 2. `depositNumber ^ (1 << level)` flips the bit at the position corresponding to the level in the depositNumber. +// 3. `(1 << level) - 1` creates a binary number with all bits to the right of the current level set to 1. +// 4. `| ((1 << level) - 1)` ensures that all bits to the right of the current level are set to 1 in the result. +// +// The function effectively finds the sibling deposit number at each level of the Merkle tree by manipulating the bits accordingly. + +func getSiblingDepositNumber(depositNumber, level uint32) uint32 { + return depositNumber ^ (1 << level) | ((1 << level) - 1) } func (p *Proof) Check() error { @@ -330,6 +379,15 @@ func generateZeroHashes(height uint8) [][TreeDepth]byte { } return zeroHashes } + +func generateEmptyHashes(height uint8) [][TreeDepth]byte { + var zeroHashes = [][TreeDepth]byte{} + zeroHashes = append(zeroHashes, common.Hash{}) + for i := 1; i <= int(height); i++ { + zeroHashes = append(zeroHashes, common.Hash{}) + } + return zeroHashes +} func checkDepositArgs(cmd *cobra.Command, args []string) error { if *ulxlyInputArgs.BridgeAddress == "" { return fmt.Errorf("please provide the bridge address") From 8a3dc6f779f762b24f0a7d73b64df2634f442167 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Tue, 4 Jun 2024 22:47:09 -0400 Subject: [PATCH 16/46] chore: minor cleanup --- cmd/ulxly/ulxly.go | 58 ++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index 45645a34..2b1feab1 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -36,11 +36,11 @@ type uLxLyArgs struct { DepositNum *uint32 } -type SMT struct { +type IMT struct { Height uint8 Branches map[uint32][][TreeDepth]byte Leaves map[uint32]common.Hash - Root [TreeDepth]byte + Roots []common.Hash ZeroHashes [][TreeDepth]byte Proofs map[uint32]Proof } @@ -152,8 +152,8 @@ func getInputData(cmd *cobra.Command, args []string) ([]byte, error) { func readDeposits(rawDeposits []byte) error { buf := bytes.NewBuffer(rawDeposits) scanner := bufio.NewScanner(buf) - smt := new(SMT) - smt.Init() + imt := new(IMT) + imt.Init() seenDeposit := make(map[uint32]common.Hash, 0) lastDeposit := uint32(0) for scanner.Scan() { @@ -172,20 +172,19 @@ func readDeposits(rawDeposits []byte) error { return fmt.Errorf("missing deposit: %d", lastDeposit+1) } lastDeposit = evt.DepositCount - smt.AddLeaf(evt) + imt.AddLeaf(evt) log.Info(). Uint64("block-number", evt.Raw.BlockNumber). Uint32("deposit-count", evt.DepositCount). Str("tx-hash", evt.Raw.TxHash.String()). - Str("root", common.Hash(smt.Root).String()). + Str("root", common.Hash(imt.Roots[len(imt.Roots)-1]).String()). Msg("adding event to tree") } - // p := smt.Proofs[*ulxlyInputArgs.DepositNum] - smt.GetProof(*ulxlyInputArgs.DepositNum) + p := imt.GetProof(*ulxlyInputArgs.DepositNum) - // fmt.Println(p.String()) + fmt.Println(p.String()) return nil } @@ -216,7 +215,7 @@ func hashDeposit(deposit *ulxly.UlxlyBridgeEvent) common.Hash { return res } -func (s *SMT) Init() { +func (s *IMT) Init() { s.Branches = make(map[uint32][][TreeDepth]byte) s.Height = TreeDepth s.Leaves = make(map[uint32]common.Hash) @@ -228,7 +227,7 @@ func (s *SMT) Init() { // cast call --rpc-url https://eth-sepolia.g.alchemy.com/v2/demo --block 4880876 0xad1490c248c5d3cbae399fd529b79b42984277df 'lastMainnetExitRoot()(bytes32)' // The first mainnet exit root for cardona is // 0x112b077c64ed4a22dfb0ab3c2622d6ddbf3a5423afeb05878c2c21c4cb5e65da -func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { +func (s *IMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { leaf := hashDeposit(deposit) log.Debug().Str("leaf-hash", common.Bytes2Hex(leaf[:])).Msg("Leaf hash calculated") // just keep a copy of the leaf indexed by deposit count for now @@ -253,10 +252,10 @@ func (s *SMT) AddLeaf(deposit *ulxly.UlxlyBridgeEvent) { node = crypto.Keccak256Hash(branches[height][:], node[:]) } s.Branches[deposit.DepositCount] = branches - s.Root = s.GetRoot(deposit.DepositCount) + s.Roots = append(s.Roots, s.GetRoot(deposit.DepositCount)) } -func (s *SMT) GetRoot(depositNum uint32) common.Hash { +func (s *IMT) GetRoot(depositNum uint32) common.Hash { node := common.Hash{} size := depositNum + 1 currentZeroHashHeight := common.Hash{} @@ -275,7 +274,7 @@ func (s *SMT) GetRoot(depositNum uint32) common.Hash { return node } -func (s *SMT) GetProof(depositNum uint32) Proof { +func (s *IMT) GetProof(depositNum uint32) Proof { node := common.Hash{} sibling := common.Hash{} size := depositNum + 1 @@ -304,15 +303,15 @@ func (s *SMT) GetProof(depositNum uint32) Proof { } p := &Proof{ Siblings: siblings, - Root: s.Root, DepositCount: depositNum, LeafHash: s.Branches[depositNum][0], } - err := p.Check() + r, err := p.Check(s.Roots) if err != nil { - log.Error().Err(err).Msg("failed to validate proof") + log.Fatal().Err(err).Msg("failed to validate proof") } + p.Root = r s.Proofs[depositNum] = *p return *p } @@ -339,7 +338,7 @@ func getSiblingDepositNumber(depositNumber, level uint32) uint32 { return depositNumber ^ (1 << level) | ((1 << level) - 1) } -func (p *Proof) Check() error { +func (p *Proof) Check(roots []common.Hash) (common.Hash, error) { node := p.LeafHash index := p.DepositCount for height := 0; height < TreeDepth; height++ { @@ -349,25 +348,24 @@ func (p *Proof) Check() error { node = crypto.Keccak256Hash(node[:], p.Siblings[height][:]) } } - isProofValid := p.Root.Cmp(node) == 0 + + isProofValid := false + for i := len(roots) - 1; i >= 0; i-- { + if roots[i].Cmp(node) == 0 { + isProofValid = true + break + } + } + log.Info(). Bool("is-proof-valid", isProofValid). Uint32("deposit-count", p.DepositCount). - Str("expected-root", p.Root.String()). Str("checked-root", node.String()).Msg("checking proof") if !isProofValid { - return fmt.Errorf("invalid proof") + return common.Hash{}, fmt.Errorf("invalid proof") } - return nil -} -func isEmpty(h [TreeDepth]byte) bool { - for i := 0; i < TreeDepth; i = i + 1 { - if h[i] != 0 { - return false - } - } - return true + return node, nil } // https://eth2book.info/capella/part2/deposits-withdrawals/contract/ From e522100c4f0d6a5388870400730849b51895cda1 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Wed, 5 Jun 2024 15:27:11 -0400 Subject: [PATCH 17/46] fix: small initialization bugs --- cmd/ulxly/ulxly.go | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index 2b1feab1..6e5195ab 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -179,7 +179,10 @@ func readDeposits(rawDeposits []byte) error { Str("tx-hash", evt.Raw.TxHash.String()). Str("root", common.Hash(imt.Roots[len(imt.Roots)-1]).String()). Msg("adding event to tree") - + // There's no point adding more leaves if we can prove the deposit already? + if evt.DepositCount >= *ulxlyInputArgs.DepositNum { + break + } } p := imt.GetProof(*ulxlyInputArgs.DepositNum) @@ -370,19 +373,19 @@ func (p *Proof) Check(roots []common.Hash) (common.Hash, error) { // https://eth2book.info/capella/part2/deposits-withdrawals/contract/ func generateZeroHashes(height uint8) [][TreeDepth]byte { - var zeroHashes = [][TreeDepth]byte{} - zeroHashes = append(zeroHashes, common.Hash{}) - for i := 1; i <= int(height); i++ { - zeroHashes = append(zeroHashes, crypto.Keccak256Hash(zeroHashes[i-1][:], zeroHashes[i-1][:])) + zeroHashes := make([][TreeDepth]byte, height) + zeroHashes[0] = common.Hash{} + for i := 1; i < int(height); i++ { + zeroHashes[i] = crypto.Keccak256Hash(zeroHashes[i-1][:], zeroHashes[i-1][:]) } return zeroHashes } func generateEmptyHashes(height uint8) [][TreeDepth]byte { - var zeroHashes = [][TreeDepth]byte{} - zeroHashes = append(zeroHashes, common.Hash{}) - for i := 1; i <= int(height); i++ { - zeroHashes = append(zeroHashes, common.Hash{}) + zeroHashes := make([][TreeDepth]byte, TreeDepth) + zeroHashes[0] = common.Hash{} + for i := 1; i < int(height); i++ { + zeroHashes[i] = common.Hash{} } return zeroHashes } From bf40ee06d73c68bc27eb763ff90a622ba3360350 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Wed, 5 Jun 2024 16:45:24 -0400 Subject: [PATCH 18/46] feat: empty proof command --- cmd/ulxly/ulxly.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index 6e5195ab..73e30f72 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -134,6 +134,24 @@ var ProofCmd = &cobra.Command{ }, } +var EmptyProofCmd = &cobra.Command{ + Use: "empty-proof", + Short: "print an empty proof structure", + Long: "TODO", + Args: cobra.NoArgs, + PreRunE: checkProofArgs, + RunE: func(cmd *cobra.Command, args []string) error { + p := new(Proof) + + e := generateEmptyHashes(TreeDepth) + for k, v := range e { + p.Siblings[k] = v + } + fmt.Println(p.String()) + return nil + }, +} + func checkProofArgs(cmd *cobra.Command, args []string) error { return nil } @@ -402,6 +420,7 @@ func checkDepositArgs(cmd *cobra.Command, args []string) error { func init() { ULxLyCmd.AddCommand(DepositsCmd) ULxLyCmd.AddCommand(ProofCmd) + ULxLyCmd.AddCommand(EmptyProofCmd) ulxlyInputArgs.FromBlock = DepositsCmd.PersistentFlags().Uint64("from-block", 0, "The block height to start query at.") ulxlyInputArgs.ToBlock = DepositsCmd.PersistentFlags().Uint64("to-block", 0, "The block height to start query at.") ulxlyInputArgs.RPCURL = DepositsCmd.PersistentFlags().String("rpc-url", "http://127.0.0.1:8545", "The RPC to query for events") From 92b6ac294b280561cadee8f55fa644dec7c3f015 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Wed, 5 Jun 2024 19:04:17 -0400 Subject: [PATCH 19/46] fix: issue with leaf selection for proof --- cmd/ulxly/ulxly.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/cmd/ulxly/ulxly.go b/cmd/ulxly/ulxly.go index 73e30f72..9d1083bf 100644 --- a/cmd/ulxly/ulxly.go +++ b/cmd/ulxly/ulxly.go @@ -152,6 +152,24 @@ var EmptyProofCmd = &cobra.Command{ }, } +var ZeroProofCmd = &cobra.Command{ + Use: "zero-proof", + Short: "print a proof structure with the zero hashes", + Long: "TODO", + Args: cobra.NoArgs, + PreRunE: checkProofArgs, + RunE: func(cmd *cobra.Command, args []string) error { + p := new(Proof) + + e := generateZeroHashes(TreeDepth) + for k, v := range e { + p.Siblings[k] = v + } + fmt.Println(p.String()) + return nil + }, +} + func checkProofArgs(cmd *cobra.Command, args []string) error { return nil } @@ -325,12 +343,12 @@ func (s *IMT) GetProof(depositNum uint32) Proof { p := &Proof{ Siblings: siblings, DepositCount: depositNum, - LeafHash: s.Branches[depositNum][0], + LeafHash: s.Leaves[depositNum], } r, err := p.Check(s.Roots) if err != nil { - log.Fatal().Err(err).Msg("failed to validate proof") + log.Error().Err(err).Msg("failed to validate proof") } p.Root = r s.Proofs[depositNum] = *p @@ -381,6 +399,7 @@ func (p *Proof) Check(roots []common.Hash) (common.Hash, error) { log.Info(). Bool("is-proof-valid", isProofValid). Uint32("deposit-count", p.DepositCount). + Str("leaf-hash", p.LeafHash.String()). Str("checked-root", node.String()).Msg("checking proof") if !isProofValid { return common.Hash{}, fmt.Errorf("invalid proof") @@ -421,6 +440,8 @@ func init() { ULxLyCmd.AddCommand(DepositsCmd) ULxLyCmd.AddCommand(ProofCmd) ULxLyCmd.AddCommand(EmptyProofCmd) + ULxLyCmd.AddCommand(ZeroProofCmd) + ulxlyInputArgs.FromBlock = DepositsCmd.PersistentFlags().Uint64("from-block", 0, "The block height to start query at.") ulxlyInputArgs.ToBlock = DepositsCmd.PersistentFlags().Uint64("to-block", 0, "The block height to start query at.") ulxlyInputArgs.RPCURL = DepositsCmd.PersistentFlags().String("rpc-url", "http://127.0.0.1:8545", "The RPC to query for events") From 6c45019d1cae863d33ff6eeb3dd5bd34c1526292 Mon Sep 17 00:00:00 2001 From: John Hilliard Date: Thu, 6 Jun 2024 12:04:17 -0400 Subject: [PATCH 20/46] docs: adding a tree diagram --- cmd/ulxly/tree-diagram.png | Bin 0 -> 237644 bytes cmd/ulxly/tree-diagram.tex | 218 +++++++++++++++++++++++++++++++++++++ 2 files changed, 218 insertions(+) create mode 100644 cmd/ulxly/tree-diagram.png create mode 100755 cmd/ulxly/tree-diagram.tex diff --git a/cmd/ulxly/tree-diagram.png b/cmd/ulxly/tree-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..9172f049d703abfbfbc1f3c499b7f5a57311cd21 GIT binary patch literal 237644 zcmeEuWmME{yYGMsB7!tX3MfbmN|(|g-Hig$-3`)>NVhadOLsGLNOy;HH_W-`dG>zy zd-mGT{&+r}F&566HTA#l>-yDYkgT*Q+7rSj5C{ZKTuewF0(qJUfjshmj0Em+?_rFC zKoES51qEfr1qEMN*;pDFn|*;mUPrn|@`|;~;`qrZR8rtR;tu4{&y#k@rwCW~qfmTY zDNuk;#dPOGg(e;xlDVXAb!b?&y|hwT;8XD8@x2!ZHwR6fSkT2QKRo7z!)~ba1@S`t zGYmr995tTyk~Oroldcyi)rH}8w^Mf zg;vxI;@OUnj!tvTtrn=mOTQOlrD4m&+r3{AEv6%Fwq~rOKkN@o5Ff%84eZoKrX%T> z$PwWYCRSoiIrb}r(rz*gs%LkpZ?3UF-8_r=Qanm1j1{8l{Sfns$?Hr+BIfIzELE{l zk2Wa(%JnN7nl)OVNIe84qi-mXj-X$Ak0uL5_1&8bx4C%6vg`uqko0egQ;p&Zn zqRNO-wh#y-CHxP9Q#QW?xD(kYO_vS|<{Fk=>yyk9iN4TrpZ zkC^}M+XB1B0a+4#P*0UUJ7-cu^X78x!fua&gM-1KV-x3F(JbYH@fQ^T^DV<>$Y1Hb z&_CQD_=y;p|MN`_o$(#{|NNX36c9}#fq!^PAzkrRLZ{4#S>)JUU-c|2Lha80&OB&zAhO$m0JEJp1So6#_TCF%~Q^yS4_p!a`udCAE zZ8iPzONTMNLxCqCj(DTK&oH?^`TcZ(X?n+#b#lI!6cic9!aSA>4bFu~zkJoo4aj+U zNp#%Ll$z313RN+=9ruNtoH+cSK5q*KEs90JPJ{y8Uq>*cZb8^1qCd;7JDVj>kv0&L zr)2Va{Yf{=ugH|tM;gf7fkG4zFZ#Dczu(a)KFL16h+%o9ug0RE`;q(?<_CJrom&lY zIh0H1mTD*4KlN58#aSmDmFi)kzVBYIOXQ843=BonzW%k|J=pEf^ASlyv>rc=ob$nP zA$}Ty2`kPo{In0cmZ*_oVw;PoTnNLEX&+)E(YUEy8_hQkz2^f_f(6nzEw_0Y zxdngT-E`+OWlN%{8L<5t%`Pn~`zj^vD%Ts+Eh#Z{@m%o^5hQ%Ftu-votY>feQLwMs@Sz~xM4lM zG_g)>NmSt-Pp9en_eNzr^|=Al7aOSz?%KQAIS=Ep?3Z#P#`lzMQM= zv*|;_B?d&7HHt`}@5$wBz0J2R5ehb1Y;v!$T1MR6-TkDemno&0KW+j_;5E(@Cs)_i z)d>Eo?cmSGK+ET@Yg!JEk+NG4_I6)O@oT(FQ zF8S75X3`>{Pi6RGS)4xFW?(HNOemDLvY>Tj0EJRn#!Hk$MkF+Vg zy_=dF<*&A{@a;$^QO!l|XihDAvRUX4&RDq`CecV1c5B_&05g&Nqz zEe=+^B$||#HndPy9frKbUV2O9w+-FlQ&2La9m%8$MlwvgA(e%lzkRB9PU@D3PnyQ- zdHR&@#>3~x)u1g`4XuEF((epvZQO30)%B8m&pG&f6ZdCbx_}b|m%hB7N6(We#~C7SIIr1u%O&aL??h{w<&R`#=;$ye)SS-dhLCX&C-RpV%jtrr5)F#?7bxQW>-TCFM0+4&va0A9(2qZ4yLs!k-YWm5<#5< zA-|s%TP(}tx)Dd6udZGoGMx^~7PG~(Unw*BUu zXjI7W)ZC>(9TiM`tOv*{qGLu{$YCy(`fgD~h6Q7)zrUa_sIm}_Cr!R{c6*b(r@=Cz zPp0qDGE>qXm5F`0rHPTc5aN|tfDJyz4{=M+K=V$s3qP$*+GzMk%sB9;A3{l319O2>1|26VA_}4`4xqTb)_chl2LMudl5@p%i$?2MOML_pO6?S`OICbLbc>pMT(EKmmVrVvFR@Me3exW_C zEe;E-RDAME`rhtwm`l~`3Ugl6;I^ob&z{^3`hM4A{}TE}#jWNjZAbO)Sg4{%`5Ao9 zW@k^KN_l&GV-ORE#>W%TYt~@M$;m;y$OZj>=rns++1m?`|5O@D7ep>7ew{5J^Z*(C z#p~CPb=-~~DbnH!2nfjLN|Th|rxX^_zq4E*7W9AG+UAG)NC`QK-LmWYY$q}~IrQ5% z48>y2=LiT0m)iv;Pw0b#!ovJ=bE%P@k%l(9Uf?;EI4(FNYgC!FmKzQ&{rS`LcYm

G(c!m8tkSX&MkPxl*91+V%v<8%CtFysNhYPV8r+Hw(4wLX~9mxG7!d71uU2 z>k|E^gb!i_g4o)*miNZ7Pf1}rrC%;Dy3uM>N-r=H|lQR|oAYENPGV)BUW~i4DFaKW3Zr&Tlem z>w`nIcg~f#4N2Ev7KgMH8CrYHGrv1nL~2)dgCMKq>Q=ieY^%^He3Hu@8s02tuZX&h zrSi32NYo`tkKO5s5mg=8G_||QBfECz9HZB3P_wZ_Bp{2kOZC~RU$(Nd6&Sx>u*%m& zcpmge?6GHf#S~5jxB`|8o@sZJ!Pg~a>+)jj9LMw8nv3?BOt2DmlWI#yrMw?b)edN%3yvI{FozK0xcqq;xOVY6Z#i9+(`k$$q5|=0! zSRX@u0vpaA76sV7kKsxcb4~UBky&j8+hTaCei=SU(%NTQAJIe<9;T<9k>U8N!n1_v z=fp`{yTXN)Sr5YLolV|C(k25gG%kDRCHci7z#JB2k2{th)kogG!(8Oovb^+vpHDoS zdmDU7T}E(tX63~8Gd$O^{b&<^c4@Q_3CWZHXN$L9)z^&8Xvm8zV+us}w9c|G$V=mS zTsbL;mWPh?&mH5S@Ub0&CnLOw(mp*didl0;UnjjEf^ZVB!^_9Zhs(`>k5+|VWi(v* zd``%M}&11$}^~q(+SAwf&F^?s|iK@|>D@H3Io~Wqw)gJ67!SyDkLCT*I7PwlXV64Hw0g zF&0*PnqXqAU$rM`iLIQ!tj%stDCS1sv)aD|2Hzi3krtUEVQ-ucKS?HYU|KdD`JZo^ zP8N6O$z{GV8h%lrqmKyDEh8vtzUSKLPw+7qNL1TBaJ#?Se2jwffq4=ZAERE>HEY=% zMyFEz31I&k=M$>$-@lidjMFA_SR*oMRMD5dreb77hkP>CxLlRp+kJ=MFqFn`$OOI)?%kz{ule~=#-Y>?sYuyZ8pG#q)(`{a7u`JB^n&a3DY#!i_M zkFcL-4R3Daj`Aj2hz4WmUVJhV4V`AeMc%Mz?Oc@Ez9ot=RTdtdye+dl-@y74B4DHg zbF0Sx$TifOfnIKPaIoWazm*`KmJY2zsA*V^t}?s6eD(*T=8v;ENkYedM%Qsq1bc~> z1icTH+oArv2jj1_|e$Ru#_he$AF%Hw69Z}Cw zQZ#^hUas7nSJ6@qyTp_K$-SjR%ie>ps_b_84%E{t74XAtM*X3h#@%|UoZ;ISgSah6 zIrY^B)=oA7hByIQ==rlrfg+Y}oU#kDCd-JtO9XRF^2b%h$GGXI4+I zte@VL;GXH|^}Xu*{&`O$#QNf3C*Ea+u7M^0+3l@qrbtpOLA4c~j(t9&2 zyZhtU(X#q|>EG~fH_A~Ro zPwI_T>*J>yoajW*LZQoXjH(-AYjS4Q5m!D<+IrpF1(^{WS#Brxqjoy7CjWhf8@pD=eFqz29G5w+xJ zyxn%N2o1V1q&yXPQ{`C`Zr<{gGdnBq;qB?Ris}*!rAkT@-r!`#)WSW%V|o-Y2#*dTlLDKtkv1i84_m8bPWi3` zUvoMrbOrtnd=>=gGJR{|$Db#Rw8NDxKj^LO>?*o%kdTm8Hq$)u<~FrzZC?FUD)7gp zQ~n{JEdhZ933)fU->e)ix68i9iGOQ|et&;+fRBQmy|L0IOF_=bnb7zxFfi|7el)GG zwi^VJH(OiQx+*w?i~!*wx^C%gA7481^k_l@c#h?Yd1S<~om^_5pGJk!2O5z43<)x} zqkE|e2pT%mR9N`Ig;$u6CRK0DP2-eUN8Wf-(}Lb=T89aCW0%_|0QS}ZMFZ&Hw|0*E zU4d~?x$^14QnYKK*h_(wa5S{0i)mKai?^JDmKj&Ww<%)b((hp<{$IgJ|2 zEy)aG!4kt)q*~O?{`JTuA3c*hz);3_DsqNFAT6sOpJCu#4%5R00yL)rN`R@Pi!SShRsw&M zZWhs0VVcy2yH!svNe>D?Umf`H`betexevS)2%BfHQlJ-Y8hwkaqz9HVM!O=5`lihbb6+~x1Bz4 zC=E(mrs^j7yz$G5iN2xOh@LtOv7WT~c-b^hzJTz2U?$79zf_-i=r(oz`rwD$#>9>|K# ze6ms<@ARqaylw_3Hn_fThxJ=!bV0>xJ{Jk$$~>CF8*VF15g7Ay9?=EDQbz>xNQI2) zyWJ7MJOMHMkg3g(9!*#F=S~T9ndkL*nZ@O!*)^w7akG>Pyh#Vm?u*1CpOo_+OG9O{ zky?zeR~9=VQ3KZ6G$#9nS+iakU7HzQ>JZuVL?V{~0^eAl+4MiAMI-Jeo&c4w7(8NR zxqSC7eQioA3|E2$F2PXz!XZ-r`lef-r9XumKT|XUPq7wU*^QyJh)7CNyzA?aOpU&& zysX@#QmH&@H@4K&QY>=mvN+eSwfsZ8;ow+Gh%^b=QLkc;biFJBHBWJQNn%H;)8A7N zcSs_^@Huc_ zp42-u)*fBjWWZqGNLgabFkg@DD^Gu>`Ex66378lhupMhSfK5U1FgBrLH0SUGV{A#g z(Iy@Gj%*n3SHGF&f|bPP;;}`>^zv@oH8$Qs1Q=b#skn0Ki5g{mqH!pV7&iNSsr+sx zhf@xeI{p&rWA&zHYCm<-&lUj`;c2?Xh`Z+qs`(a=STf5wlYWLVAZ=8At~0V9uAF!$ z^mwxanlt|!u zFhF-;kQ)sTTvDGUvUK6c$*v?x>$&Q7BnA=G>v3trJaA?r_MdD@Fp9V%o$D;0g0pdU z5J^;1c7v68dcW(YzfVbf_p%lc&IL7Btn42gawVf9qmh7Op?&YLrdysJ|`~5bp|rlg8LKKPp6K z&wDq?RG#NxIN&JOdi(fb0(A)Js(M$)>wd^1T6GWzDZfYP=1|%Lh{;$Uf~%`*R&Fl- zHTU!9&oP38@>EJlo85q1iKQ=3!NoI}C3HGowE1c0Q%F~%dZK3W+*)3mr+GQGXo(q@ zPhAS(^Gc00)@Zr|AsJo;NBVbfMkuBF+5mttVy#K(v5#@|o{hG7{rMi=S~GM zm3FzCY@{uIOQWxo@_GstFsKlhKZX34v;dosJmi!rsM|(VfU65puAp1G5IE|7y=UCyKXGsxN(^%Ole_ToFBDk^#0~@T*)Qt<>+*hHAfu z3?`w^yB8SQJiK9ylYsYQt7GCG8SF~bC_9GaJlO#>T@7YZ9S^Uuc>O8_gi^&ht%Z`W z@vdx4l@ei7$Rkd6=X?PE6d!78&f{NYb!*5F)Z+<`yJ$OoktZAT%%;&!z5EF(Ozh?F zB&c3fz1xOua3VKdKAUXpc3mD^eqdF8oqq|?L14Fh&9D%}VzDW#yIbt^U{S~FOJ8^Q z@cl)t?dB8SF6d_Gny&1(4c*ScL3E%Q1O^Awo;qe^WDIACW7pKymLUMwCFaE_)`&By zvxN}F^`Oq=((F$*vyL3Uc$1i!ERtUWl49XG(A<@yb>uuuS?F3FmPxJTLfN7B5jP$m z5XOGdt3~$4Bvs(e5~eOmhXxADM;~F&IX=_&nNofV)Lc7KY->s!$dY`mH>e#aBi*5z zZv;S^+~O&A2tWceWmhUlt!mTKjqIsB)J5{n`Mvi)H`of-{Yo zyJ{0HCXN~t2cl8dgha;x{aQuspLas9H;aJK@cB4$XyoU&q;CggjgQ`!M-`+W^!z0b zUtdl7ceGAy@u@0i^A2h#m{E4vkm$HTNT7BB3c`jV;YY%+#x8SSPkH){$b{0UNLsyX zEAfXwOsa}B8V(whJJ>T}@lPZ34s&T z*PQie`ZS+E{&>y?4{&AudgO1%?=T^scJf?#Y^>}bLQ?9X8eHLq9x@!x;ek8;wh|PP zj~QcF*Pjk?rkek-Q={EyJeYjn&zlt2E#kY)z#1}9Fg6kyf<3*~)7b;6WVGcGCbma{c{HICFPuN9|wFAQ%qoqsnPiteX! z1_o3fSL^ssiP)Y}iiUUWPM2G64W}bQQ~2Bo@tL$c&UPlPSG&+O>+DddWm0|R^T$ZB zF)_cMYz{q!jJy127GM>KQ8f;GgoDYPJ{=t$ZU?q!+e&VyBce__Mb&RC<~Ry9Yvnf) zQEU|evSl^Ji)GZJ?MC`tXK&gc&-?(cU&rZqs9ipiIt|gXFdcJ>#MxSG<_8^4b19z+ z7+KFqc`(-62th;pMXy6K6WF1<<-AJfoEjM)4vx>EsksXl%eM4X$XXtA{bBq!Vt1P> za!AWi^KNusbWmzmw-e}E58ha0Y#wDJUr{wnMml_nNdR?#0w3&74JFTbR?6 zm}SrQ=ybpuJ1p@T4r#^P+x)8>i7?e`Qy&SF-;2{Ho}rdr66h!jgjnKC+xY6Bc7nEP zZGYpuhd$i(3C3{ep=(wvFle0m&Rs%nP(i;8?Q4Cd=tiGdIjAw z5B!swH_S!*KA596rWb&@FaNjO0SeV*ERz!mGv2^_(x58rnjsIVWOqPpX=SQz2fccp ze;exXtYsvS=;12|EXaEU8zlMES20fi(c!w*qK~Tzd`maY9w2_|sj27Det^=bDG-_) zde;1){OG96IlksVfuy!3cLsJosHWOGHGT`;6*(2hlff8GKrsX5>ygSfc0QOAzLoqE zK9`U^`(7>I6w)ox)6xDGw$gUJT64FlBsThsUVc&_2v>sQZ~XVNmEm2j;{homBBIrD z+oM9&GQ=b{^R}&#%%dLav`-y@nBD#TW2E)Qqg0Y9T)3dk8O_(Rf)Wi-Dp3BAE^8D~ z3sjNo(?335UXTj&S-dp&^XI92v04eRxj!t_JT>c9hLxD6S1*jQLi-d z!={#2y**)6uXwE275ZVlH^y)Jy_s35(Fn!vd_Dd^A}if#Jdj-=5FTFM6NYyQ?~Jj) zZ2tP{W9%BYM`tjum7^o{^v~$@1HcU>WEbWwOsevcg{w3Vn&;;CL&b$e=Uosh)zSE2 zGgNVO?91kqn3*mii7tIOFb=#R%)}lYz3-Wr?4%FgC(x>h4X#<8;jwtFVBw4-gZPnMTB*iN*F?18)uTnAPb!F`p>n--=QcGa~d8 z&Y`b|q(f`n)8AkrYbX|MhLt9h6f=Ct+bhU(OEfNiaJsjh(8s+wb*$Pfu+GFJs zjG<1G>mecJ$CVeG3%+!;5I^R&Gb$v@SZ(UGbx5`s$H}oBr-ER(tI&LL?E1`D`$5^W z)NPX4V8O>g@2JEikAZ8hB}`SHm)I#K^h23wf!qPObea7MArH`tly;my6e)go9x6G! zV6O+t#I$G84;Z0FakoYy$u0>U7dZplBkr8S0K@j}t($dOC)VO{DLv0F!21N#H&Jv# zE#Cph;r(#g?AGj)`m8*=NK$u5Ug|Yv)(k zN(eM5Gm6KC*7wb_V%QEv;?0*r;W%ezY@D-e?*4=p($eViWsJGh>qi5?jkw@q5-sY$ zS-_k1Zu~s?dcu?WFR!H;8Et{nkbxHMSLd%D_K`^XGt4k4k~Ho~2~|^|J4V=}BEFGu zzlp!BhSx!V&-x5b0&?7q<@Nxh$zl?Cg@zHaw{?j`m6}eKlCxRN1)`I1{jgc@z5J7# z27&BMmIO#-3v3RiSRbtj!y9k8!9edtDsUY-rppbN4-O(gCtj(X)RuGzBjYCpkB9QZ zZhf>HU5sgkC|c)gZ7~T50zK}o$zQ&F$j8Trch&IW!-pDh68Ua+-xip^9~l|paJzg1 zS-LrB4gg@KX=7!@8=RU?+hh3zd~O^wRpucY)fVKhUOmc{P7%nKh?)BPEbL1wvgs1- zrqs$ElpUKr|E z(lqX#&;1V_)!k^vOjtDw{#a_%vOikWl04R7bJp&Y7;hH*uJ8(9Xdb;>(-X(2o{2VB zf)R3h08RriOeu&W<)E?I*SIFIfgJ#Q0rB@riQ+|KApSgdVKL%CQF;=qN!vaVWcm#! z#w$-l25wN2kt79xOCEad4%9cAvz@inQRMd3iYQHk#&i4@4oju7Ft1*Fm+{XJpYACZ z+IrLIxyd~?cYDf7<{P;~ZEULv&<}h{-45SXX2jO^n;N|QgQPIi^h)n< z5%3Ss`ux~4xL>M4UEJC}dhsoVyc5{xaz$U+yUbFb0G|g4fR)<6D}pL&aJsX93G7gv zFNctb$wyjKfw7VTOSx^zS)3NIiS5fwLxJ`WeET?c#iMK z6^~DoJF-K#L#Wok8ZaJ+wM&VBGfa8@;T_?**;k;uK6j_&J(-{2Hi+*fu6_Hl`s*+G zN$YgxQb&iDL#5RU{sLhCbJTGyN67UtZ_PR$9(OEkG;ZLF6@L2j_nG+quyR=cca}I9 z0UZ(i_jy|S-wVuVtG0e;qfQj6`6RqG%y2o|hP;!Rg98zyrvzT0%j2jTAwocArrjT{ zuey5;RQly!_2O`~rOqBjR6~wTT6pvQH7Y7TV+T;|`tQ}0XmR0p0&t{Z{~(dgoDi7w z@c9B4Ae`oBXNkBScD*zip}=x`WBmK&)bw=OCWr;Zc+Uyh4X~ZPxeB}&vRj%cpE_@@ z6rs)-U40kz4X%X6&{*1>#)!KQ8xAJ9L@aVyqZM0l8`{~t1JoA1Sej}wMz#;von4bV zfp`0&Cl6+W-3axZ-_--~hKP0K0mRrkA1+3mR>jCnUK7!|#kwj>|Zw56!no(xibozAwBCTha^t-yF>oNo5_vO?< zUwYnRrEya{!tgHMbeV65 zbc};tJ$0bKq{Dnuh`pL5FbCVjgPS?v;NY5@F=zajDZO$D1e5ngB1y|B))&L}VhV3D zZ;!Zy0d7`;>-sb9V|ILhJWSam8ul z!Z&jB4OMQIF)Al#cE4E_!dEz_OD+Cdn64=hmfMfHYWcjGFxZS!JLRmdb*KNBxE{|B zoZg0Jb3)K@bjf%+M>=nqOP2NRQhwt%8lcl!&Fg%heDP)7MRx1TLNA`q(cll8EZ+7^ zlQ(78etftHuLh1&(dbkvM}rkRx_c!y15(8ZH#>PW$e)yXXRivvBat6}VM=@$OyLe# zg+^pb#Lzx|{P^{0Jh(%UDry-Z`zw$88Pk&1$w~Zbi+O=hpIWtW?=M%Mx!oQ?uRPc+ z7kEIl;dEc?(qzkFZ>ALxL})lkdH1GPlN+Z$I>{3m8JPle9wK&&4)ByCm8L4YGnF3? zI%|rG7(g7QrW+(=^P<`=fD3afF-2=#JHG8B4hr=<>4vxbC9&zC0 zd=-mYb$H^AbUvO+R?cV=~u7~${Wynqxzmvoa(;OzSki;O+Dk%Q$fWH5;`>7 z@`-G|f7WzgX$@ikQ*W+w175Hh-K4lgkRRfrg6hxTYc4iL& zky-7#XED`6eWhHg?*_6)Li)zpb;B=#r3mcC2N2C>4-&}I>Z*^gude`1sW8tubOVUA z$BhxH^j%YBdI%6;XAWGbi-;iY&({ZlN?X5i-d`+G%$HC1qyu@n7+R&aC~BD>vakEE zYXt=btpUUjC1mY2A(B>AC7_Z?4Q14-TN>hr`TF=ga0O&E(rXi?;A+Qu7;z%aDgkY z%6_l{W&bJVtg;1`X7*Sks__De1RAe%3*V-_aMj#@6qwD90(lgXd&8^k*t=?@#hZNG z01O+x#|P&3Q+e~)A2ZS(pEaE6q%0gDlob&G&y3@8-J!e+_rgYDi4y^Phg&$h*hQQr=i%pR$ z2MLEF<+A^5bXNUpiaeSKLm+5x0IqBJm?gP~$_O<&W-s^jhz&)=OuuS5Dv zfofI^rcSaX0o{}*!>A|1Kyf#<2Tvd{OViIkqDkH?FigulbXmA&!hfa$qIw?y@YS5Q zLGo!P%XieB_)F_jKd#5<<*;Ne3xo8=5MTy~8p1l`2gu@j2`r0N^|t(8=w}=!Spb?-R9WHdMlyWSEH_)7TWoWwi3!V zMVh)-uTeYa*VhTV3433SIsN1SrbzIaCCuw9>cWRjYu-muA#@@3cRC*Tm6b4ek9j!& zrd4UdSY39J?S_w4ZbyS2cvC|&N`2z!3d2<_R$|cMr>8%_J9$B95<^HqBo_qThz-T1 z=kx%b1yfBupYa_E3d+~!=4Pr=MPrArM@L7k)r%gc$F9zfKIJF(^X<3b?0$8H97^VLVe#PZn!cp6Lgc zmzSUSFvWgLNeTP<069Y;S6a19*G~<98K|+5k5-G5=Plec#@TA#%E@7kpfe_-r~xm@ zt5@VMTs>Q4s}soiSB~9?5LbNUtgf7RMHK-Cm4%?xI=uKT=OYq>go!Gf`*4u>RNw38 zZ!Ka_88n>i1W`B03tm2@P3BsAi=9u%Lr8osi%fK^r~u&+&nNfK;QP%q1=GL>7U;P+&r@DrO8J5f-hAo|QxPnLZ_r4I-Q%~?{+$-K&;6)Vh<{G0UxAxJw# z(`{{;^E45JG7(DBp4uA+=QJj3*y4QE7(#?xyPZ=3&&ec~d4UiLokEs@M<)Sjf#*rN zLTPGx!sLs)9h*MGD!uPbe`tbOA!2tk!Bw+jFTS(B;G&^(h$Uoc`Hw3k*a17|-vnE$ zREaQgkzJo$kTja*im*PhgT^x`lnukMc~FCO>tWBp8GE<4sea;;^B%Y)uuSHX6p&>~l7Lr~dj5y1*3HdrX?Hgi+;s06GvE#q zAV)t=&f??absJ&7zVy*6JH$x%VN#0x0QGsfk!1O#p~+x?u;KLgN28I9N3MAAQ4H{( z#!BQSWNE)3!Kq)W@HwT9O-0mIRA!=$(g&d4Q;o;T_Qg16iiP7Mtw?3joEEVy^&M)|IS*&9G@-!Cr-F;SU-B%nt?g}5J%}bcoiR5F zq0&Ed_0>IorQWHOfRM-(yXjl1-84Ty4W2Z3I1KP_9cnw?p-Rz@$@tnWa2?nutx#;bkWZGKga)11p#sBzrt>)kcSe*eIOF&h%lpb}-gr%}SdUDBu`?S)k6R zXoAFZ1u8Q4o>U%?rJ`B<&K-%*cyPOj{}ni&uu2VfElgmyv6)<)1VJ(2M^&}vVnpXU zq@^(WHHHYLm-y+RK7ur|KUM$BCLnMQCq%FZl|s%f_(UzXaCm+N*zIt@ywHijIy;v(1tt9UsG20ln_aJcQkptVq`xq1A@Lez{#r+OiOke?zHtO zy{8tGEfh*CzMX()7moSbvb>X!ewuDb8fC#Yx4-6cDp=UMI|;gH4XXTgM2(|xv%b2yS&fq68@VcxCK(va-J7W#z3-pOO;DYQrcoGfa6S>hPk^+HWQs2D z?G0!P3kkh^b4BKC(V-U;@-46!A} zhUDp5EFJl7?Fe*pQL67YVi(B^)D-y2pVO;k?hh<$_B;ZLglumN*R{Y)$dAt#8%QvV z-qDve%A+Z#Qo$1MPgCAR-DJwns#s_9jM6VTvQp%yCPbtADFW?ki~BQ3%e;PjMptp4 z1ZHyMTecM+k~EyU?uU>zM6%}%=@YX2J<@Riv0F9GFBR=ItSj$zwqa_eu`+M+YVy*x zHM*?pRsulD?nx%;4S*JBnbO#SfEW;0JK$lmY^W1hn1RNTzE3o`9t;q8PS%)o-3Gcn zAKyLh%+sB$iv#wpiT+PFY=$rfle^f>dsDO8pA#1o`(mW->oap78w=@ zru~q2Mg^+%)A?I%fGK)Zqc&whY;2E5sn%dT+4|*N9^a=es>|cw`<}Z;uQtXABS2*B zbrzG*3n22_bF)uaXv)c3yUCrPfQjB`%TZfzWO*Hq7Cs>d!-RObXeGWkqcZ>{Yuh!S z(?u#AzV|SG71yNJmrw@Rk3u6n?4YF0)HdL+Z--RJ&C3MM-RVwM2zX@0oX$L=D%4Z> zzf`HnZ#$=yGo|LS8j(IX)$4ct`mH;{CX2LP=MtiBG*<9xV?jN~mXD%(w`g%&Hlxg0 ze2qqu0U3<<$l-YVbn*Q`&n{wi!$D#vXXg(TBRq=Ppz7k8^^kz5!)7-169aL>;!l3}rpjnxwKlOOv@cvDq?6&1P8mJ?AMtxl{o=KS2Sx`*<$> z^MaGI=|7VOiNtJsSjsVPUJ$Y(ZsT0LfYf2Xe^~GrD{pX)BJ_%yJp3j+-(vkPy*@iwp0434Hs_Df z`-pA?BhhLg6K$IJ*&{0!bP%apNHTnShOHL+^d!kMG^WJer|~Vj`kr$E2w=;N)MN4S zv6T#8cmgL+UiUj#BIoxkP=!ZU7n$1o*>!Igk-XnKz8S75c(_lNCYlRcaRaqzUzkR)WOOg-xVE(3uI9PW zQRp4FtuuI=F-OFHzq6d+NnVAkH(Y)2rs*o8K?cjt%KDu%JYaqq1cYu6EO zBVD>$Gb9;yMgW$z=J)m;2!IJ8h?+Aj`w>ib`wwr(Bq$S_w3{xvF%s2`sJph`=rywn#H;Y;@Xc&2!XVB?dh+GY z?VXMeAr5Z*xgL7p3jl1;+3JHlQmj?)Rx*&p{)}2Wxg|HvBRG~pBSQ}wex=D2?2EL^L(8>SH#KjaohHI0kdw$<4^)-#Mx@g0M*+Ss>I!0vrynk zEPC9Se_fQ4km$W=-iQX!eRuMSwU+pM%&YI<+G{U``WM*PaMo8LJ9&K`07F3P7s!LGAqZw2Y=I3|4}sw(SDS-u_A)V^o{}8x z&yg_*#D|X3y<5kc701BFc?9sI;%R>2TbhJ|iH~S6u!1n0cTnI4?@yb29Eq2{ogWfY z{Xo{th}z}X+bky+CPeh&@VvDP-AGHY)$nVy90Qv;jN4Ot+zlxR4P2A9)^QY&c4n#Xl89(}KOJ z0G^NjH?TPYdHsfsw^?7vuPvOU=apHfQcbHZy-u1*0|aOTI$D(hrQ(0?g-m_0G{jVu z?hxQ#>gddTWb@_ZxzHjC)HR9EJE}fpp&8%);R8g}|I7k#Kc&rnQaOv?Da0n}n>OltAexR>MA^|4?=^TWlxtVl!3`KCv31p(39JsFCNsViIk