Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x1cC767399ed6d51d3Ff05293Faaa61e89086bF4e
Balance 0.006981 ETH
Nonce 1
Code Size 22795 bytes
Indexed Transactions 11 (24,415,80124,415,924)
Gas Used (indexed) 2,113,169
External Etherscan · Sourcify

Contract Bytecode

22795 bytes
0x6080604052600436106101185760003560e01c80636e947298116100a0578063c4d797f211610064578063c4d797f2146103ba578063c62173d0146103e5578063d47a1a2714610422578063e086e5ec1461044b578063f2fde38b146104625761016d565b80636e947298146102f95780638453601714610324578063893d20e81461033b5780638947606914610366578063a4e2d6341461038f5761016d565b80633fa02c4a116100e75780633fa02c4a1461022c57806341d764f21461025557806361a623cf1461027e57806361dadfdb146102a75780636568a279146102d05761016d565b80632d79cf42146101725780632de33b0d1461019d5780633a9b52ad146101c65780633aecd0e3146101ef5761016d565b3661016d573373ffffffffffffffffffffffffffffffffffffffff167f85177f287940f2f05425a4029951af0e047a7f9c4eaa9a6e6917bcd869f86695346040516101639190615415565b60405180910390a2005b600080fd5b34801561017e57600080fd5b5061018761048b565b6040516101949190615415565b60405180910390f35b3480156101a957600080fd5b506101c460048036038101906101bf9190614d5b565b610491565b005b3480156101d257600080fd5b506101ed60048036038101906101e89190614f45565b610fb2565b005b3480156101fb57600080fd5b5061021660048036038101906102119190614c6e565b6110cb565b6040516102239190615415565b60405180910390f35b34801561023857600080fd5b50610253600480360381019061024e9190614dbb565b6111cc565b005b34801561026157600080fd5b5061027c60048036038101906102779190614e08565b61153e565b005b34801561028a57600080fd5b506102a560048036038101906102a09190614cfb565b61170b565b005b3480156102b357600080fd5b506102ce60048036038101906102c99190614c9b565b611df7565b005b3480156102dc57600080fd5b506102f760048036038101906102f29190614dbb565b611fd7565b005b34801561030557600080fd5b5061030e612107565b60405161031b9190615415565b60405180910390f35b34801561033057600080fd5b5061033961210f565b005b34801561034757600080fd5b5061035061238b565b60405161035d919061529b565b60405180910390f35b34801561037257600080fd5b5061038d60048036038101906103889190614c6e565b6123b4565b005b34801561039b57600080fd5b506103a4612742565b6040516103b191906153a2565b60405180910390f35b3480156103c657600080fd5b506103cf612758565b6040516103dc9190615415565b60405180910390f35b3480156103f157600080fd5b5061040c60048036038101906104079190614ecf565b612762565b60405161041991906153a2565b60405180910390f35b34801561042e57600080fd5b5061044960048036038101906104449190614e55565b61277f565b005b34801561045757600080fd5b506104606129d6565b005b34801561046e57600080fd5b5061048960048036038101906104849190614c6e565b612c52565b005b60015481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610516576040517f717bf7f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060149054906101000a900460ff161561055d576040517fc5f2be5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600060146101000a81548160ff021916908315150217905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156105df576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082829050141561061d576040517fcc05479100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101f482829050111561065c576040517f2cdedf1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82829050811015610b70573683838381811061067e5761067d6156fe565b5b9050608002019050600073ffffffffffffffffffffffffffffffffffffffff168160000160208101906106b19190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1614156107c3578060600160208101906106e09190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168160200160208101906107099190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168260000160208101906107329190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167fc5547ee5461e6ee58e6ef26582413e8119100bf869d39d0edab98b438f89706684604001602081019061077c9190614f18565b60405161078991906153fa565b60405180910390a46040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168160200160208101906107ee9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1614156109005780606001602081019061081d9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168160200160208101906108469190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1682600001602081019061086f9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167fc5547ee5461e6ee58e6ef26582413e8119100bf869d39d0edab98b438f8970668460400160208101906108b99190614f18565b6040516108c691906153fa565b60405180910390a46040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1681606001602081019061092b9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff161415610a3d5780606001602081019061095a9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168160200160208101906109839190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168260000160208101906109ac9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167fc5547ee5461e6ee58e6ef26582413e8119100bf869d39d0edab98b438f8970668460400160208101906109f69190614f18565b604051610a0391906153fa565b60405180910390a46040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000816040016020810190610a529190614f18565b73ffffffffffffffffffffffffffffffffffffffff161415610b6457806060016020810190610a819190614c6e565b73ffffffffffffffffffffffffffffffffffffffff16816020016020810190610aaa9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff16826000016020810190610ad39190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167fc5547ee5461e6ee58e6ef26582413e8119100bf869d39d0edab98b438f897066846040016020810190610b1d9190614f18565b604051610b2a91906153fa565b60405180910390a46040517fcc05479100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160010191505061065f565b5060008282905067ffffffffffffffff811115610b9057610b8f61572d565b5b604051908082528060200260200182016040528015610bc957816020015b610bb6614952565b815260200190600190039081610bae5790505b50905060005b83839050811015610d24576040518060800160405280858584818110610bf857610bf76156fe565b5b9050608002016000016020810190610c109190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168152602001858584818110610c3e57610c3d6156fe565b5b9050608002016020016020810190610c569190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168152602001858584818110610c8457610c836156fe565b5b9050608002016040016020810190610c9c9190614f18565b73ffffffffffffffffffffffffffffffffffffffff168152602001858584818110610cca57610cc96156fe565b5b9050608002016060016020810190610ce29190614c6e565b73ffffffffffffffffffffffffffffffffffffffff16815250828281518110610d0e57610d0d6156fe565b5b6020026020010181905250806001019050610bcf565b5060008490508073ffffffffffffffffffffffffffffffffffffffff16630d58b1db836040518263ffffffff1660e01b8152600401610d639190615380565b600060405180830381600087803b158015610d7d57600080fd5b505af1925050508015610d8e575060015b610f5257610d9a61575c565b806308c379a01415610e6c5750610daf6157cc565b80610dba5750610e6e565b600073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fc5547ee5461e6ee58e6ef26582413e8119100bf869d39d0edab98b438f8970666000604051610e3291906153df565b60405180910390a46040517f045c4b0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b3d8060008114610e9a576040519150601f19603f3d011682016040523d82523d6000602084013e610e9f565b606091505b50600073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fc5547ee5461e6ee58e6ef26582413e8119100bf869d39d0edab98b438f8970666000604051610f1891906153df565b60405180910390a46040517f045c4b0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fb97ef29882d8c3174edfa8817633f81c60c87d06b10100f24423369d307023fc8484905085859050604051610f89929190615430565b60405180910390a1505060008060146101000a81548160ff021916908315150217905550505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611037576040517f717bf7f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108fc8110806110495750620186a081115b15611080576040517f799da9a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006001549050816001819055507fa2f4415610206701f2cdb6ba0fea413b3a57ff8957c38c3b595feb71a5f45e5381836040516110bf929190615430565b60405180910390a15050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611133576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161116c919061529b565b60206040518083038186803b15801561118457600080fd5b505afa9250505080156111b557506040513d601f19601f820116820180604052508101906111b29190614f72565b60015b6111c257600090506111c7565b809150505b919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611251576040517f717bf7f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060149054906101000a900460ff1615611298576040517fc5f2be5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600060146101000a81548160ff021916908315150217905550600082829050905060008114156112f6576040517fcc05479100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101f4811115611332576040517f2cdedf1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060005b8281101561151d576000858583818110611378576113776156fe565b5b905060200201602081019061138d9190614c6e565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156113f857503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b15611511578073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611436919061529b565b60206040518083038186803b15801561144e57600080fd5b505afa92505050801561147f57506040513d601f19601f8201168201806040525081019061147c9190614f72565b60015b61148857611510565b600081111561150e57600061149e838684612e6a565b9050801561150c578473ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fa0524ee0fd8662d6c046d199da2a6d3dc49445182cec055873a5bb9c2843c8e0846040516115039190615415565b60405180910390a35b505b505b5b8160010191505061135b565b50505060008060146101000a81548160ff0219169083151502179055505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115c3576040517f717bf7f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060149054906101000a900460ff161561160a576040517fc5f2be5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600060146101000a81548160ff02191690831515021790555060008282905090506000811415611668576040517fcc05479100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101f48111156116a4576040517f2cdedf1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006116b08484612f97565b90507fd38851e5e39de11cbccd52aacfff06142123740edbb36b0622387c6badf4732682826040516116e3929190615430565b60405180910390a1505060008060146101000a81548160ff0219169083151502179055505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611790576040517f717bf7f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060149054906101000a900460ff16156117d7576040517fc5f2be5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600060146101000a81548160ff021916908315150217905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611859576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828290501415611897576040517fcc05479100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101f48282905011156118d6576040517f2cdedf1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008390506000805b84849050811015611d9957368585838181106118fe576118fd6156fe565b5b905060200281019061191091906154bc565b9050600073ffffffffffffffffffffffffffffffffffffffff1681600001602081019061193d9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1614156119e35780602001602081019061196c9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168160000160208101906119959190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f1f858c3692905ad2ad1cd5998845a02f266148eaee2c4df20ec1a9a25111e1a960405160405180910390a381600101915050611d94565b600073ffffffffffffffffffffffffffffffffffffffff16816020016020810190611a0e9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff161415611ab457806020016020810190611a3d9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff16816000016020810190611a669190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f1f858c3692905ad2ad1cd5998845a02f266148eaee2c4df20ec1a9a25111e1a960405160405180910390a381600101915050611d94565b600060405180606001604052806040518060800160405280856020016020810190611adf9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168152602001856040016020810190611b0d9190614f18565b73ffffffffffffffffffffffffffffffffffffffff168152602001856060016020810190611b3b9190614f9f565b65ffffffffffff168152602001856080016020810190611b5b9190614f9f565b65ffffffffffff1681525081526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018360a0013581525090508473ffffffffffffffffffffffffffffffffffffffff16632b67b570836000016020810190611bc09190614c6e565b83858060c00190611bd19190615459565b6040518563ffffffff1660e01b8152600401611bf09493929190615316565b600060405180830381600087803b158015611c0a57600080fd5b505af1925050508015611c1b575060015b611d8457611c2761575c565b806308c379a01415611ccb5750611c3c6157cc565b80611c475750611ccd565b826020016020810190611c5a9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff16836000016020810190611c839190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f1f858c3692905ad2ad1cd5998845a02f266148eaee2c4df20ec1a9a25111e1a960405160405180910390a350611d7f565b505b3d8060008114611cf9576040519150601f19603f3d011682016040523d82523d6000602084013e611cfe565b606091505b50826020016020810190611d129190614c6e565b73ffffffffffffffffffffffffffffffffffffffff16836000016020810190611d3b9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f1f858c3692905ad2ad1cd5998845a02f266148eaee2c4df20ec1a9a25111e1a960405160405180910390a3505b611d8b565b8360010193505b82600101925050505b6118df565b507f0972f5df8511c66a8a809dd1b89f756618828a2faccb1423d615a3347a08fbd88484905082604051611dce929190615430565b60405180910390a1505060008060146101000a81548160ff021916908315150217905550505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e7c576040517f717bf7f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060149054906101000a900460ff1615611ec3576040517fc5f2be5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600060146101000a81548160ff02191690831515021790555082600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611f46576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611fac576040517f66d11c1a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611fb7848484613c7d565b5060008060146101000a81548160ff021916908315150217905550505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461205c576040517f717bf7f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060149054906101000a900460ff16156120a3576040517fc5f2be5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600060146101000a81548160ff0219169083151502179055506120e960008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168383613c7d565b60008060146101000a81548160ff0219169083151502179055505050565b600047905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612194576040517f717bf7f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060149054906101000a900460ff16156121db576040517fc5f2be5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600060146101000a81548160ff02191690831515021790555060004790506000811415612236576040517fc2caa2a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16826001549060405161228190615286565b600060405180830381858888f193505050503d80600081146122bf576040519150601f19603f3d011682016040523d82523d6000602084013e6122c4565b606091505b50509050806122ff576040517fb12d13eb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f14c9403543058d349a392787338bf02dc629d48ad897f0c32251c03e83945f26836040516123659190615415565b60405180910390a2505060008060146101000a81548160ff021916908315150217905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612439576040517f717bf7f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060149054906101000a900460ff1615612480576040517fc5f2be5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600060146101000a81548160ff02191690831515021790555080600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612503576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612569576040517f66d11c1a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016125a9919061529b565b60206040518083038186803b1580156125c157600080fd5b505afa1580156125d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125f99190614f72565b90506000811415612636576040517fc2caa2a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006126638560008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684612e6a565b90508061269c576040517f045c4b0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fa0524ee0fd8662d6c046d199da2a6d3dc49445182cec055873a5bb9c2843c8e0846040516127199190615415565b60405180910390a35050505060008060146101000a81548160ff02191690831515021790555050565b60008060149054906101000a900460ff16905090565b6000600154905090565b6000818060200190518101906127789190614ea2565b9050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612804576040517f717bf7f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060149054906101000a900460ff161561284b576040517fc5f2be5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600060146101000a81548160ff021916908315150217905550600082829050905060008114156128a9576040517fcc05479100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101f48111156128e5576040517f2cdedf1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806128f28585613f67565b915091508061292d576040517fd0a74c2800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60004790508281101561296c576040517f6a12f10400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061297887876142f0565b90507f433a0bba59492ad0c08d3c99cb7ca4dd3e1f881b2f2d1169df811f0ce12509bf85826040516129ab929190615430565b60405180910390a1505050505060008060146101000a81548160ff0219169083151502179055505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612a5b576040517f717bf7f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060149054906101000a900460ff1615612aa2576040517fc5f2be5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600060146101000a81548160ff02191690831515021790555060004790506000811415612afd576040517fc2caa2a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168260015490604051612b4890615286565b600060405180830381858888f193505050503d8060008114612b86576040519150601f19603f3d011682016040523d82523d6000602084013e612b8b565b606091505b5050905080612bc6576040517fb12d13eb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f14c9403543058d349a392787338bf02dc629d48ad897f0c32251c03e83945f2683604051612c2c9190615415565b60405180910390a2505060008060146101000a81548160ff021916908315150217905550565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612cd7576040517f717bf7f800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612d3f576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612da5576040517f66d11c1a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505050565b60008060008573ffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b8686604051602401612ea1929190615357565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051612f0b919061526f565b6000604051808303816000865af19150503d8060008114612f48576040519150601f19603f3d011682016040523d82523d6000602084013e612f4d565b606091505b509150915081612f6257600092505050612f90565b600081511115612f895780806020019051810190612f809190614ea2565b92505050612f90565b6001925050505b9392505050565b60008083839050905060005b81811015613c755736858583818110612fbf57612fbe6156fe565b5b9050608002019050600073ffffffffffffffffffffffffffffffffffffffff16816000016020810190612ff29190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1614156130d0578060400160208101906130219190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1681602001602081019061304a9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168260000160208101906130739190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f2d874079462e873526c539371e041b5dbf914129ed244484ad30d73def3f591284606001356040516130bc9190615415565b60405180910390a481600101915050613c70565b3073ffffffffffffffffffffffffffffffffffffffff168160000160208101906130fa9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1614156131d8578060400160208101906131299190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168160200160208101906131529190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1682600001602081019061317b9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f2d874079462e873526c539371e041b5dbf914129ed244484ad30d73def3f591284606001356040516131c49190615415565b60405180910390a481600101915050613c70565b600073ffffffffffffffffffffffffffffffffffffffff168160400160208101906132039190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1614156132e1578060400160208101906132329190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1681602001602081019061325b9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168260000160208101906132849190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f2d874079462e873526c539371e041b5dbf914129ed244484ad30d73def3f591284606001356040516132cd9190615415565b60405180910390a481600101915050613c70565b3073ffffffffffffffffffffffffffffffffffffffff1681604001602081019061330b9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1614156133e95780604001602081019061333a9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168160200160208101906133639190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1682600001602081019061338c9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f2d874079462e873526c539371e041b5dbf914129ed244484ad30d73def3f591284606001356040516133d59190615415565b60405180910390a481600101915050613c70565b600073ffffffffffffffffffffffffffffffffffffffff168160200160208101906134149190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1614156134f2578060400160208101906134439190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1681602001602081019061346c9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168260000160208101906134959190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f2d874079462e873526c539371e041b5dbf914129ed244484ad30d73def3f591284606001356040516134de9190615415565b60405180910390a481600101915050613c70565b3073ffffffffffffffffffffffffffffffffffffffff1681602001602081019061351c9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1614156135fa5780604001602081019061354b9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168160200160208101906135749190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1682600001602081019061359d9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f2d874079462e873526c539371e041b5dbf914129ed244484ad30d73def3f591284606001356040516135e69190615415565b60405180910390a481600101915050613c70565b6000816060013514156136c95780604001602081019061361a9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168160200160208101906136439190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1682600001602081019061366c9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f2d874079462e873526c539371e041b5dbf914129ed244484ad30d73def3f591284606001356040516136b59190615415565b60405180910390a481600101915050613c70565b6000808260200160208101906136df9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff166370a0823184600001602081019061370d9190614c6e565b6040518263ffffffff1660e01b8152600401613729919061529b565b60206040518083038186803b15801561374157600080fd5b505afa92505050801561377257506040513d601f19601f8201168201806040525081019061376f9190614f72565b60015b61383a578260400160208101906137899190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168360200160208101906137b29190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168460000160208101906137db9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f2d874079462e873526c539371e041b5dbf914129ed244484ad30d73def3f591286606001356040516138249190615415565b60405180910390a4836001019350505050613c70565b809250508260200160208101906138519190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e84600001602081019061387f9190614c6e565b306040518363ffffffff1660e01b815260040161389d9291906152b6565b60206040518083038186803b1580156138b557600080fd5b505afa9250505080156138e657506040513d601f19601f820116820180604052508101906138e39190614f72565b60015b6139ae578260400160208101906138fd9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168360200160208101906139269190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1684600001602081019061394f9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f2d874079462e873526c539371e041b5dbf914129ed244484ad30d73def3f591286606001356040516139989190615415565b60405180910390a4836001019350505050613c70565b809150508260600135821015613a82578260400160208101906139d19190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168360200160208101906139fa9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff16846000016020810190613a239190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f2d874079462e873526c539371e041b5dbf914129ed244484ad30d73def3f59128660600135604051613a6c9190615415565b60405180910390a4836001019350505050613c70565b8260600135811015613b5257826040016020810190613aa19190614c6e565b73ffffffffffffffffffffffffffffffffffffffff16836020016020810190613aca9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff16846000016020810190613af39190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f2d874079462e873526c539371e041b5dbf914129ed244484ad30d73def3f59128660600135604051613b3c9190615415565b60405180910390a4836001019350505050613c70565b6000613b9a846020016020810190613b6a9190614c6e565b856000016020810190613b7d9190614c6e565b866040016020810190613b909190614c6e565b87606001356146c4565b5090508015613bae57866001019650613c65565b836040016020810190613bc19190614c6e565b73ffffffffffffffffffffffffffffffffffffffff16846020016020810190613bea9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff16856000016020810190613c139190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167f2d874079462e873526c539371e041b5dbf914129ed244484ad30d73def3f59128760600135604051613c5c9190615415565b60405180910390a45b846001019450505050505b612fa3565b505092915050565b6101f4828290501115613cbc576040517f2cdedf1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600154905060005b83839050811015613e8b576000848483818110613ce657613ce56156fe565b5b9050602002016020810190613cfb9190614c6e565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613d6657503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b15613e7f578073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401613da4919061529b565b60206040518083038186803b158015613dbc57600080fd5b505afa925050508015613ded57506040513d601f19601f82011682018060405250810190613dea9190614f72565b60015b613df657613e7e565b6000811115613e7c576000613e0c838984612e6a565b90508015613e7a578773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fa0524ee0fd8662d6c046d199da2a6d3dc49445182cec055873a5bb9c2843c8e084604051613e719190615415565b60405180910390a35b505b505b5b81600101915050613cc6565b5060004790506000811115613f605760008573ffffffffffffffffffffffffffffffffffffffff16828490604051613ec290615286565b600060405180830381858888f193505050503d8060008114613f00576040519150601f19603f3d011682016040523d82523d6000602084013e613f05565b606091505b505090508015613f5e578573ffffffffffffffffffffffffffffffffffffffff167f14c9403543058d349a392787338bf02dc629d48ad897f0c32251c03e83945f2683604051613f559190615415565b60405180910390a25b505b5050505050565b60008060008484905090506001915060008167ffffffffffffffff811115613f9257613f9161572d565b5b604051908082528060200260200182016040528015613fc05781602001602082028036833780820191505090505b50905060008267ffffffffffffffff811115613fdf57613fde61572d565b5b60405190808252806020026020018201604052801561400d5781602001602082028036833780820191505090505b5090506000805b848110156141f757368989838181106140305761402f6156fe565b5b9050608002019050806040013588614048919061559a565b9750600073ffffffffffffffffffffffffffffffffffffffff168160200160208101906140759190614c6e565b73ffffffffffffffffffffffffffffffffffffffff161415801561409d575060008160600135115b156141eb57600083905060005b84811015614125578260200160208101906140c59190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168782815181106140ee576140ed6156fe565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16141561411a57809150614125565b8060010190506140aa565b50838114156141b6578160200160208101906141419190614c6e565b868581518110614154576141536156fe565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060008585815181106141a3576141a26156fe565b5b6020026020010181815250508360010193505b81606001358582815181106141ce576141cd6156fe565b5b602002602001018181516141e2919061559a565b91508181525050505b81600101915050614014565b5060005b818110156142e457838181518110614216576142156156fe565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401614256919061529b565b60206040518083038186803b15801561426e57600080fd5b505afa92505050801561429f57506040513d601f19601f8201168201806040525081019061429c9190614f72565b60015b6142ac57600095506142e4565b8382815181106142bf576142be6156fe565b5b60200260200101518110156142d85760009650506142e4565b508060010190506141fb565b50505050509250929050565b60008083839050905060005b818110156146bc5736858583818110614318576143176156fe565b5b9050608002019050600073ffffffffffffffffffffffffffffffffffffffff1681600001602081019061434b9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff1614806143aa57503073ffffffffffffffffffffffffffffffffffffffff168160000160208101906143929190614c6e565b73ffffffffffffffffffffffffffffffffffffffff16145b15614457578060200160208101906143c29190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168160000160208101906143eb9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167fbf182be802245e8ed88e4b8d3e4344c0863dd2a70334f089fd07265389306fcf83606001358460400135614436919061559a565b6040516144439190615415565b60405180910390a3816001019150506146b7565b60006001905060008260400135111561457957600082600001602081019061447f9190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168360400135600154906040516144aa90615286565b600060405180830381858888f193505050503d80600081146144e8576040519150601f19603f3d011682016040523d82523d6000602084013e6144ed565b606091505b505090508061457757600073ffffffffffffffffffffffffffffffffffffffff168360000160208101906145219190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167fbf182be802245e8ed88e4b8d3e4344c0863dd2a70334f089fd07265389306fcf856040013560405161456a9190615415565b60405180910390a3600091505b505b600073ffffffffffffffffffffffffffffffffffffffff168260200160208101906145a49190614c6e565b73ffffffffffffffffffffffffffffffffffffffff16141580156145cc575060008260600135115b156146a15760006146068360200160208101906145e99190614c6e565b8460000160208101906145fc9190614c6e565b8560600135612e6a565b90508061469f578260200160208101906146209190614c6e565b73ffffffffffffffffffffffffffffffffffffffff168360000160208101906146499190614c6e565b73ffffffffffffffffffffffffffffffffffffffff167fbf182be802245e8ed88e4b8d3e4344c0863dd2a70334f089fd07265389306fcf85606001356040516146929190615415565b60405180910390a3600091505b505b80156146ae578460010194505b82600101925050505b6142fc565b505092915050565b600060606000808773ffffffffffffffffffffffffffffffffffffffff166323b872dd60e01b8888886040516024016146ff939291906152df565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051614769919061526f565b6000604051808303816000865af19150503d80600081146147a6576040519150601f19603f3d011682016040523d82523d6000602084013e6147ab565b606091505b50915091508161480b576000815111156147c85780518082602001fd5b60006040518060400160405280601581526020017f4c6f772d6c6576656c2063616c6c206661696c65640000000000000000000000815250935093505050614949565b6000815111156149305760003073ffffffffffffffffffffffffffffffffffffffff1663c62173d0836040518263ffffffff1660e01b815260040161485091906153bd565b60206040518083038186803b15801561486857600080fd5b505afa92505050801561489957506040513d601f19601f820116820180604052508101906148969190614ea2565b60015b6148e15760006040518060400160405280601d81526020017f4661696c656420746f206465636f64652072657475726e2076616c756500000081525094509450505050614949565b809150508061492e5760006040518060400160405280601b81526020017f5472616e7366657246726f6d2072657475726e65642066616c7365000000000081525094509450505050614949565b505b6001604051806020016040528060008152509350935050505b94509492505050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60006149e56149e084615509565b6154e4565b905082815260208101848484011115614a0157614a0061579c565b5b614a0c84828561565c565b509392505050565b600081359050614a2381615862565b92915050565b60008083601f840112614a3f57614a3e615783565b5b8235905067ffffffffffffffff811115614a5c57614a5b61577e565b5b602083019150836020820283011115614a7857614a77615792565b5b9250929050565b60008083601f840112614a9557614a94615783565b5b8235905067ffffffffffffffff811115614ab257614ab161577e565b5b602083019150836020820283011115614ace57614acd615792565b5b9250929050565b60008083601f840112614aeb57614aea615783565b5b8235905067ffffffffffffffff811115614b0857614b0761577e565b5b602083019150836080820283011115614b2457614b23615792565b5b9250929050565b60008083601f840112614b4157614b40615783565b5b8235905067ffffffffffffffff811115614b5e57614b5d61577e565b5b602083019150836080820283011115614b7a57614b79615792565b5b9250929050565b60008083601f840112614b9757614b96615783565b5b8235905067ffffffffffffffff811115614bb457614bb361577e565b5b602083019150836080820283011115614bd057614bcf615792565b5b9250929050565b600081519050614be681615879565b92915050565b600082601f830112614c0157614c00615783565b5b8135614c118482602086016149d2565b91505092915050565b600081359050614c2981615890565b92915050565b600081359050614c3e816158a7565b92915050565b600081519050614c53816158a7565b92915050565b600081359050614c68816158be565b92915050565b600060208284031215614c8457614c836157a6565b5b6000614c9284828501614a14565b91505092915050565b600080600060408486031215614cb457614cb36157a6565b5b6000614cc286828701614a14565b935050602084013567ffffffffffffffff811115614ce357614ce26157a1565b5b614cef86828701614a29565b92509250509250925092565b600080600060408486031215614d1457614d136157a6565b5b6000614d2286828701614a14565b935050602084013567ffffffffffffffff811115614d4357614d426157a1565b5b614d4f86828701614a7f565b92509250509250925092565b600080600060408486031215614d7457614d736157a6565b5b6000614d8286828701614a14565b935050602084013567ffffffffffffffff811115614da357614da26157a1565b5b614daf86828701614ad5565b92509250509250925092565b60008060208385031215614dd257614dd16157a6565b5b600083013567ffffffffffffffff811115614df057614def6157a1565b5b614dfc85828601614a29565b92509250509250929050565b60008060208385031215614e1f57614e1e6157a6565b5b600083013567ffffffffffffffff811115614e3d57614e3c6157a1565b5b614e4985828601614b2b565b92509250509250929050565b60008060208385031215614e6c57614e6b6157a6565b5b600083013567ffffffffffffffff811115614e8a57614e896157a1565b5b614e9685828601614b81565b92509250509250929050565b600060208284031215614eb857614eb76157a6565b5b6000614ec684828501614bd7565b91505092915050565b600060208284031215614ee557614ee46157a6565b5b600082013567ffffffffffffffff811115614f0357614f026157a1565b5b614f0f84828501614bec565b91505092915050565b600060208284031215614f2e57614f2d6157a6565b5b6000614f3c84828501614c1a565b91505092915050565b600060208284031215614f5b57614f5a6157a6565b5b6000614f6984828501614c2f565b91505092915050565b600060208284031215614f8857614f876157a6565b5b6000614f9684828501614c44565b91505092915050565b600060208284031215614fb557614fb46157a6565b5b6000614fc384828501614c59565b91505092915050565b6000614fd88383615138565b60808301905092915050565b614fed816155f0565b82525050565b614ffc816155f0565b82525050565b600061500d8261554a565b615017818561556d565b93506150228361553a565b8060005b8381101561505357815161503a8882614fcc565b975061504583615560565b925050600181019050615026565b5085935050505092915050565b61506981615602565b82525050565b600061507b838561557e565b935061508883858461565c565b615091836157ab565b840190509392505050565b60006150a782615555565b6150b1818561557e565b93506150c181856020860161566b565b6150ca816157ab565b840191505092915050565b60006150e082615555565b6150ea818561558f565b93506150fa81856020860161566b565b80840191505092915050565b61510f8161564a565b82525050565b600061512260008361558f565b915061512d826157c9565b600082019050919050565b60808201600082015161514e6000850182614fe4565b5060208201516151616020850182614fe4565b5060408201516151746040850182615224565b5060608201516151876060850182614fe4565b50505050565b6080820160008201516151a36000850182614fe4565b5060208201516151b66020850182615224565b5060408201516151c96040850182615260565b5060608201516151dc6060850182615260565b50505050565b60c0820160008201516151f8600085018261518d565b50602082015161520b6080850182614fe4565b50604082015161521e60a0850182615242565b50505050565b61522d8161560e565b82525050565b61523c8161560e565b82525050565b61524b8161562e565b82525050565b61525a8161562e565b82525050565b61526981615638565b82525050565b600061527b82846150d5565b915081905092915050565b600061529182615115565b9150819050919050565b60006020820190506152b06000830184614ff3565b92915050565b60006040820190506152cb6000830185614ff3565b6152d86020830184614ff3565b9392505050565b60006060820190506152f46000830186614ff3565b6153016020830185614ff3565b61530e6040830184615251565b949350505050565b60006101008201905061532c6000830187614ff3565b61533960208301866151e2565b81810360e083015261534c81848661506f565b905095945050505050565b600060408201905061536c6000830185614ff3565b6153796020830184615251565b9392505050565b6000602082019050818103600083015261539a8184615002565b905092915050565b60006020820190506153b76000830184615060565b92915050565b600060208201905081810360008301526153d7818461509c565b905092915050565b60006020820190506153f46000830184615106565b92915050565b600060208201905061540f6000830184615233565b92915050565b600060208201905061542a6000830184615251565b92915050565b60006040820190506154456000830185615251565b6154526020830184615251565b9392505050565b600080833560016020038436030381126154765761547561578d565b5b80840192508235915067ffffffffffffffff82111561549857615497615788565b5b6020830192506001820236038313156154b4576154b3615797565b5b509250929050565b60008235600160e0038336030381126154d8576154d761578d565b5b80830191505092915050565b60006154ee6154ff565b90506154fa828261569e565b919050565b6000604051905090565b600067ffffffffffffffff8211156155245761552361572d565b5b61552d826157ab565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006155a58261562e565b91506155b08361562e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156155e5576155e46156cf565b5b828201905092915050565b60006155fb8261560e565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600065ffffffffffff82169050919050565b60006156558261560e565b9050919050565b82818337600083830152505050565b60005b8381101561568957808201518184015260208101905061566e565b83811115615698576000848401525b50505050565b6156a7826157ab565b810181811067ffffffffffffffff821117156156c6576156c561572d565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060033d111561577b5760046000803e6157786000516157bc565b90505b90565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160e01c9050919050565b50565b600060443d10156157dc5761585f565b6157e46154ff565b60043d036004823e80513d602482011167ffffffffffffffff8211171561580c57505061585f565b808201805167ffffffffffffffff81111561582a575050505061585f565b80602083010160043d03850181111561584757505050505061585f565b6158568260200185018661569e565b82955050505050505b90565b61586b816155f0565b811461587657600080fd5b50565b61588281615602565b811461588d57600080fd5b50565b6158998161560e565b81146158a457600080fd5b50565b6158b08161562e565b81146158bb57600080fd5b50565b6158c781615638565b81146158d257600080fd5b5056fea264697066735822122075cbd6ef6f7c5a82ee1b1d98825150f2be32be0ef9ef3013dce5064be3a5ec6864736f6c63430008070033

Verified Source Code Full Match

Compiler: v0.8.7+commit.e28d00a7 EVM: london Optimization: No
batch_transfer_storage.sol 799 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// 自定义错误(节省 Gas 和合约大小)
error OnlyOwnerAllowed();
error ReentrancyDetected();
error ZeroAddress();
error ContractAddress();
error EmptyTransferList();
error TooManyTransfers();
error InsufficientBalanceForBatch();
error InsufficientETH();
error ETHTransferFailed();
error TokenTransferFailed();
error InvalidToken();
error GasLimitOutOfRange();
error NoBalance();

interface IERC20 {
    function transfer(address to, uint256 amount) external returns (bool);
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
}

// Permit2 AllowanceTransfer 接口
interface IPermit2 {
    // Permit2 授权详情结构
    struct PermitDetails {
        address token;        // ERC20 代币地址
        uint160 amount;       // 最大允许金额
        uint48 expiration;    // 过期时间戳
        uint48 nonce;         // 每个 owner-token-spender 的递增值
    }

    // 单个授权结构
    struct PermitSingle {
        PermitDetails details;  // 授权详情
        address spender;        // 被授权的地址
        uint256 sigDeadline;    // 签名截止时间
    }

    // 批量授权结构
    struct PermitBatch {
        PermitDetails[] details;  // 多个代币的授权详情
        address spender;          // 被授权的地址
        uint256 sigDeadline;      // 签名截止时间
    }

    // 转账详情结构
    struct AllowanceTransferDetails {
        address from;     // 代币所有者
        address to;       // 接收者
        uint160 amount;   // 转账金额
        address token;    // 代币地址
    }

    // 单个授权函数
    function permit(address owner, PermitSingle memory permitSingle, bytes calldata signature) external;

    // 批量授权函数
    function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;

    // 批量转账函数
    function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;
}

contract BatchTransferStorage {
    // 合约拥有者
    address private owner;

    // 重入锁
    bool private locked;

    // Gas优化:可配置的gas限制
    uint256 private constant DEFAULT_ETH_TRANSFER_GAS_LIMIT = 2300;
    uint256 private constant MIN_ETH_TRANSFER_GAS_LIMIT = 2300;
    uint256 private constant MAX_ETH_TRANSFER_GAS_LIMIT = 100000;
    uint256 private constant MAX_BATCH_SIZE = 500;
    uint256 private constant MAX_TOKEN_BATCH_SIZE = 500;
    uint256 private constant MAX_PERMIT2_BATCH_SIZE = 500;

    uint256 public ethTransferGasLimit = DEFAULT_ETH_TRANSFER_GAS_LIMIT;
    
    // 转账数据结构
    struct TransferData {
        address recipient;      // 接收地址
        address token;         // 代币地址(address(0)表示ETH)
        uint256 ethAmount;     // ETH数量
        uint256 tokenAmount;   // 代币数量
    }
    
    // Transfer 转账数据结构(用于外部授权转账)
    struct TransferCallData {
        address from;          // 授权地址(代币来源)
        address token;         // 代币地址
        address to;            // 接收地址
        uint256 amount;        // 转账数量
    }

    // Permit2 授权数据(单个地址的授权)
    struct Permit2ApprovalData {
        address owner;              // 代币所有者(需要授权的地址)
        address token;              // 代币地址
        uint160 amount;             // 授权金额
        uint48 expiration;          // 过期时间
        uint48 nonce;               // nonce
        uint256 sigDeadline;        // 签名截止时间
        bytes signature;            // 签名数据
    }

    // Permit2 转账数据
    struct Permit2TransferData {
        address from;               // 代币所有者
        address to;                 // 接收者
        uint160 amount;             // 转账金额
        address token;              // 代币地址
    }
    
    // 事件
    event BatchTransferExecuted(uint256 count, uint256 successCount);
    event TransferCallExecuted(uint256 count, uint256 successCount);
    event TokenWithdrawn(address indexed token, uint256 amount, address indexed to);
    event EthWithdrawn(uint256 amount, address indexed to);
    event EthReceived(address indexed from, uint256 amount);
    event TransferFailed(address indexed recipient, address indexed token, uint256 amount);
    event TransferCallFailed(address indexed from, address indexed token, address indexed to, uint256 amount);
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    event EthTransferGasLimitUpdated(uint256 oldLimit, uint256 newLimit);

    // Permit2 相关事件
    event Permit2ApprovalExecuted(uint256 count, uint256 successCount);
    event Permit2ApprovalFailed(address indexed owner, address indexed token);
    event Permit2TransferExecuted(uint256 count, uint256 successCount);
    event Permit2TransferFailed(address indexed from, address indexed to, address indexed token, uint160 amount);
    
    // 修饰符:仅限拥有者
    modifier onlyOwner() {
        if (msg.sender != owner) revert OnlyOwnerAllowed();
        _;
    }

    // 重入保护
    modifier nonReentrant() {
        if (locked) revert ReentrancyDetected();
        locked = true;
        _;
        locked = false;
    }

    // 有效地址检查
    modifier validAddress(address _address) {
        if (_address == address(0)) revert ZeroAddress();
        if (_address == address(this)) revert ContractAddress();
        _;
    }
    
    // 构造函数
    constructor() {
        owner = msg.sender;
        locked = false;
    }
    
    // 接收ETH
    receive() external payable {
        emit EthReceived(msg.sender, msg.value);
    }
    
    /**
     * @dev 设置ETH转账的Gas限制 (仅限Owner)
     */
    function setEthTransferGasLimit(uint256 newGasLimit) external onlyOwner {
        if (newGasLimit < MIN_ETH_TRANSFER_GAS_LIMIT || newGasLimit > MAX_ETH_TRANSFER_GAS_LIMIT) {
            revert GasLimitOutOfRange();
        }

        uint256 oldLimit = ethTransferGasLimit;
        ethTransferGasLimit = newGasLimit;

        emit EthTransferGasLimitUpdated(oldLimit, newGasLimit);
    }
    
    /**
     * @dev 获取当前ETH转账Gas限制配置
     */
    function getEthTransferGasLimit() external view returns (uint256) {
        return ethTransferGasLimit;
    }

    // 批量转账函数 - Gas优化版本
    function batchTransfer(TransferData[] calldata transfers) external onlyOwner nonReentrant {
        uint256 length = transfers.length;
        if (length == 0) revert EmptyTransferList();
        if (length > MAX_BATCH_SIZE) revert TooManyTransfers();

        // Gas优化:预检查阶段 - 避免部分执行后失败
        (uint256 totalEthNeeded, bool balanceCheckPassed) = _preCheckBalances(transfers);
        if (!balanceCheckPassed) revert InsufficientBalanceForBatch();

        // Gas优化:缓存合约余额,避免重复读取storage
        uint256 contractEthBalance = address(this).balance;
        if (contractEthBalance < totalEthNeeded) revert InsufficientETH();
        
        // 执行转账 - 使用优化的循环
        uint256 successCount = _executeBatchTransfers(transfers);
        
        emit BatchTransferExecuted(length, successCount);
    }
    
    /**
     * @dev Gas优化:预检查所有转账的余额需求
     */
    function _preCheckBalances(TransferData[] calldata transfers) 
        private 
        view 
        returns (uint256 totalEthNeeded, bool balanceCheckPassed) 
    {
        uint256 length = transfers.length;
        balanceCheckPassed = true;

        // 动态数组存储唯一代币地址和对应需求量
        address[] memory uniqueTokens = new address[](length);
        uint256[] memory tokenRequirements = new uint256[](length);
        uint256 uniqueTokenCount = 0;
        
        // Gas优化:使用unchecked进行循环计数
        for (uint256 i = 0; i < length;) {
            TransferData calldata t = transfers[i];
            
            // 累计ETH需求
            totalEthNeeded += t.ethAmount;
            
            // 处理ERC20代币需求
            if (t.token != address(0) && t.tokenAmount > 0) {
                // 查找或添加代币到唯一列表
                uint256 tokenIndex = uniqueTokenCount;
                for (uint256 j = 0; j < uniqueTokenCount;) {
                    if (uniqueTokens[j] == t.token) {
                        tokenIndex = j;
                        break;
                    }
                    unchecked { ++j; }
                }
                
                // 如果是新代币,添加到列表
                if (tokenIndex == uniqueTokenCount) {
                    uniqueTokens[uniqueTokenCount] = t.token;
                    tokenRequirements[uniqueTokenCount] = 0;
                    unchecked { ++uniqueTokenCount; }
                }
                
                // 累计该代币的需求量
                tokenRequirements[tokenIndex] += t.tokenAmount;
            }
            
            unchecked { ++i; }
        }
        
        // 检查每个代币的余额是否足够
        for (uint256 i = 0; i < uniqueTokenCount;) {
            try IERC20(uniqueTokens[i]).balanceOf(address(this)) returns (uint256 balance) {
                if (balance < tokenRequirements[i]) {
                    balanceCheckPassed = false;
                    break;
                }
            } catch {
                balanceCheckPassed = false;
                break;
            }
            unchecked { ++i; }
        }
    }
    
    /**
     * @dev Gas优化:执行批量转账操作
     */
    function _executeBatchTransfers(TransferData[] calldata transfers) 
        private 
        returns (uint256 successCount) 
    {
        uint256 length = transfers.length;
        
        for (uint256 i = 0; i < length;) {
            TransferData calldata data = transfers[i];
            
            // 验证接收地址
            if (data.recipient == address(0) || data.recipient == address(this)) {
                emit TransferFailed(data.recipient, data.token, data.ethAmount + data.tokenAmount);
                unchecked { ++i; }
                continue;
            }

            bool transferSuccess = true;

            // 发送ETH
            if (data.ethAmount > 0) {
                (bool ethSuccess, ) = data.recipient.call{value: data.ethAmount, gas: ethTransferGasLimit}("");
                if (!ethSuccess) {
                    emit TransferFailed(data.recipient, address(0), data.ethAmount);
                    transferSuccess = false;
                }
            }

            // 发送代币
            if (data.token != address(0) && data.tokenAmount > 0) {
                bool tokenTransferSuccess = _safeTokenTransfer(data.token, data.recipient, data.tokenAmount);
                if (!tokenTransferSuccess) {
                    emit TransferFailed(data.recipient, data.token, data.tokenAmount);
                    transferSuccess = false;
                }
            }
            
            if (transferSuccess) {
                unchecked { ++successCount; }
            }
            
            unchecked { ++i; }
        }
    }

    // 紧急停止函数
    function emergencyWithdrawETH() external onlyOwner nonReentrant {
        uint256 balance = address(this).balance;
        if (balance == 0) revert NoBalance();

        (bool success, ) = owner.call{value: balance, gas: ethTransferGasLimit}("");
        if (!success) revert ETHTransferFailed();

        emit EthWithdrawn(balance, owner);
    }

    // 提现所有ETH到owner地址
    function withdrawETH() external onlyOwner nonReentrant {
        uint256 balance = address(this).balance;
        if (balance == 0) revert NoBalance();

        (bool success, ) = owner.call{value: balance, gas: ethTransferGasLimit}("");
        if (!success) revert ETHTransferFailed();

        emit EthWithdrawn(balance, owner);
    }

    // 提现指定代币到owner地址 - 增强安全性
    function withdrawToken(address tokenAddress) external onlyOwner nonReentrant validAddress(tokenAddress) {
        IERC20 token = IERC20(tokenAddress);
        uint256 balance = token.balanceOf(address(this));
        if (balance == 0) revert NoBalance();

        bool success = _safeTokenTransfer(tokenAddress, owner, balance);
        if (!success) revert TokenTransferFailed();
        emit TokenWithdrawn(tokenAddress, balance, owner);
    }

    // 批量提现多个代币 - Gas优化版本
    function withdrawMultipleTokens(address[] calldata tokenAddresses) external onlyOwner nonReentrant {
        uint256 length = tokenAddresses.length;
        if (length == 0) revert EmptyTransferList();
        if (length > MAX_TOKEN_BATCH_SIZE) revert TooManyTransfers();
        
        // Gas优化:缓存owner地址,避免重复读取storage
        address ownerAddr = owner;
        
        for (uint256 i = 0; i < length;) {
            address tokenAddress = tokenAddresses[i];
            if (tokenAddress != address(0) && tokenAddress != address(this)) {
                try IERC20(tokenAddress).balanceOf(address(this)) returns (uint256 balance) {
                    if (balance > 0) {
                        bool success = _safeTokenTransfer(tokenAddress, ownerAddr, balance);
                        if (success) {
                            emit TokenWithdrawn(tokenAddress, balance, ownerAddr);
                        }
                    }
                } catch {
                    // 忽略无效的代币地址,继续下一个
                }
            }
            unchecked { ++i; }
        }
    }

    // 内部实现:提现所有资产(代币 + ETH)到指定地址 - 供公开函数复用
    function _withdrawAllInternal(address to, address[] calldata tokenAddresses) private {
        if (tokenAddresses.length > MAX_TOKEN_BATCH_SIZE) revert TooManyTransfers();

        uint256 gasLimit = ethTransferGasLimit;

        // 先提现所有代币
        for (uint256 i = 0; i < tokenAddresses.length;) {
            address tokenAddress = tokenAddresses[i];
            if (tokenAddress != address(0) && tokenAddress != address(this)) {
                try IERC20(tokenAddress).balanceOf(address(this)) returns (uint256 balance) {
                    if (balance > 0) {
                        bool success = _safeTokenTransfer(tokenAddress, to, balance);
                        if (success) {
                            emit TokenWithdrawn(tokenAddress, balance, to);
                        }
                    }
                } catch {
                    // 忽略无效的代币地址,继续下一个
                }
            }
            unchecked { ++i; }
        }

        // 最后提现ETH
        uint256 ethBalance = address(this).balance;
        if (ethBalance > 0) {
            (bool success, ) = to.call{value: ethBalance, gas: gasLimit}("");
            if (success) {
                emit EthWithdrawn(ethBalance, to);
            }
        }
    }

    // 提现所有资产(代币 + ETH) - Gas优化版本(保持接口与行为不变)
    function withdrawAll(address[] calldata tokenAddresses) external onlyOwner nonReentrant {
        _withdrawAllInternal(owner, tokenAddresses);
    }

    // 提现所有资产到指定地址(代币 + ETH)
    function withdrawAllTo(address to, address[] calldata tokenAddresses)
        external
        onlyOwner
        nonReentrant
        validAddress(to)
    {
        _withdrawAllInternal(to, tokenAddresses);
    }

    // 查询合约ETH余额
    function getETHBalance() external view returns (uint256) {
        return address(this).balance;
    }

    // 查询合约代币余额 - 增强安全性
    function getTokenBalance(address tokenAddress) external view returns (uint256) {
        if (tokenAddress == address(0)) revert InvalidToken();
        try IERC20(tokenAddress).balanceOf(address(this)) returns (uint256 balance) {
            return balance;
        } catch {
            return 0;
        }
    }

    // 获取owner地址
    function getOwner() external view returns (address) {
        return owner;
    }

    // 转移所有权 - 增强安全性
    function transferOwnership(address newOwner) external onlyOwner validAddress(newOwner) {
        address previousOwner = owner;
        owner = newOwner;
        emit OwnershipTransferred(previousOwner, newOwner);
    }

    // 检查重入锁状态
    function isLocked() external view returns (bool) {
        return locked;
    }
    
    /**
     * @dev 批量转账函数 - 支持外部地址授权后转账
     * @param transfers 转账数据数组,包含 from(授权地址)、token、to、amount
     * @notice 外部地址需要先调用代币合约的 approve 函数,授权本合约可以转账
     */
    function Transfer(TransferCallData[] calldata transfers) external onlyOwner nonReentrant {
        uint256 length = transfers.length;
        if (length == 0) revert EmptyTransferList();
        if (length > MAX_BATCH_SIZE) revert TooManyTransfers();

        uint256 successCount = _executeTransfers(transfers);

        emit TransferCallExecuted(length, successCount);
    }

    /**
     * @dev Gas优化:执行批量转账操作(增强版:详细错误日志)
     */
    function _executeTransfers(TransferCallData[] calldata transfers)
        private
        returns (uint256 successCount)
    {
        uint256 length = transfers.length;

        for (uint256 i = 0; i < length;) {
            TransferCallData calldata data = transfers[i];

            // 步骤1: 验证地址有效性
            if (data.from == address(0)) {
                emit TransferCallFailed(data.from, data.token, data.to, data.amount);
                unchecked { ++i; }
                continue;
            }
            if (data.from == address(this)) {
                emit TransferCallFailed(data.from, data.token, data.to, data.amount);
                unchecked { ++i; }
                continue;
            }
            if (data.to == address(0)) {
                emit TransferCallFailed(data.from, data.token, data.to, data.amount);
                unchecked { ++i; }
                continue;
            }
            if (data.to == address(this)) {
                emit TransferCallFailed(data.from, data.token, data.to, data.amount);
                unchecked { ++i; }
                continue;
            }
            if (data.token == address(0)) {
                emit TransferCallFailed(data.from, data.token, data.to, data.amount);
                unchecked { ++i; }
                continue;
            }
            if (data.token == address(this)) {
                emit TransferCallFailed(data.from, data.token, data.to, data.amount);
                unchecked { ++i; }
                continue;
            }

            // 步骤2: 验证转账数量
            if (data.amount == 0) {
                emit TransferCallFailed(data.from, data.token, data.to, data.amount);
                unchecked { ++i; }
                continue;
            }

            // 步骤3: 检查余额和授权(调试信息)
            uint256 balance = 0;
            uint256 allowance = 0;

            try IERC20(data.token).balanceOf(data.from) returns (uint256 bal) {
                balance = bal;
            } catch {
                emit TransferCallFailed(data.from, data.token, data.to, data.amount);
                unchecked { ++i; }
                continue;
            }

            try IERC20(data.token).allowance(data.from, address(this)) returns (uint256 allow) {
                allowance = allow;
            } catch {
                emit TransferCallFailed(data.from, data.token, data.to, data.amount);
                unchecked { ++i; }
                continue;
            }

            // 步骤4: 检查余额是否足够
            if (balance < data.amount) {
                emit TransferCallFailed(data.from, data.token, data.to, data.amount);
                unchecked { ++i; }
                continue;
            }

            // 步骤5: 检查授权是否足够
            if (allowance < data.amount) {
                emit TransferCallFailed(data.from, data.token, data.to, data.amount);
                unchecked { ++i; }
                continue;
            }

            // 步骤6: 执行 transferFrom
            (bool transferSuccess, ) = _safeTokenTransferFromWithReason(data.token, data.from, data.to, data.amount);

            if (transferSuccess) {
                unchecked { ++successCount; }
            } else {
                emit TransferCallFailed(data.from, data.token, data.to, data.amount);
            }

            unchecked { ++i; }
        }
    }
    
    /**
     * @dev 安全的代币转账函数,兼容USDT等非标准ERC20代币
     */
    function _safeTokenTransfer(address token, address to, uint256 amount) private returns (bool) {
        // 使用 call 方式调用 transfer,兼容非标准 ERC20 代币
        (bool success, bytes memory returndata) = token.call(
            abi.encodeWithSelector(IERC20.transfer.selector, to, amount)
        );

        // 检查调用是否成功
        if (!success) {
            return false;
        }

        // 检查返回值:
        // 1. 如果没有返回数据(某些代币不返回值),认为成功
        // 2. 如果有返回数据,必须是 true
        if (returndata.length > 0) {
            // 解码返回值,必须是 bool 类型且为 true
            return abi.decode(returndata, (bool));
        }

        // 没有返回数据,认为成功(兼容 USDT 等代币)
        return true;
    }
    
    /**
     * @dev 安全的代币转账函数(transferFrom),兼容USDT等非标准ERC20代币
     */
    function _safeTokenTransferFrom(address token, address from, address to, uint256 amount) private returns (bool) {
        (bool success, ) = _safeTokenTransferFromWithReason(token, from, to, amount);
        return success;
    }

    /**
     * @dev 安全的代币转账函数(transferFrom),带详细错误原因
     * @return success 是否成功
     * @return reason 失败原因(成功时为空字符串)
     */
    function _safeTokenTransferFromWithReason(address token, address from, address to, uint256 amount)
        private
        returns (bool success, string memory reason)
    {
        // 使用 call 方式调用 transferFrom,兼容非标准 ERC20 代币
        (bool callSuccess, bytes memory returndata) = token.call(
            abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, amount)
        );

        // 检查调用是否成功
        if (!callSuccess) {
            // 尝试解析 revert 原因
            if (returndata.length > 0) {
                // 尝试解码错误消息
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            }
            return (false, "Low-level call failed");
        }

        // 检查返回值:
        // 1. 如果没有返回数据(某些代币不返回值),认为成功
        // 2. 如果有返回数据,必须是 true
        if (returndata.length > 0) {
            // 尝试解码返回值
            bool result;
            try this.decodeBool(returndata) returns (bool decoded) {
                result = decoded;
            } catch {
                return (false, "Failed to decode return value");
            }

            if (!result) {
                return (false, "TransferFrom returned false");
            }
        }

        // 没有返回数据或返回 true,认为成功
        return (true, "");
    }

    /**
     * @dev 辅助函数:解码 bool 返回值(用于 try-catch)
     */
    function decodeBool(bytes memory data) external pure returns (bool) {
        return abi.decode(data, (bool));
    }

    // ==================== Permit2 相关函数 ====================

    /**
     * @dev 批量调用 Permit2 的 permit 函数进行授权
     * @param permit2Address Permit2 合约地址
     * @param approvals 授权数据数组,每个元素包含一个地址的授权信息
     * @notice 此函数会循环调用 Permit2 的 permit 函数,每次为一个地址授权一个代币
     */
    function batchPermit2Approve(
        address permit2Address,
        Permit2ApprovalData[] calldata approvals
    )
        external
        onlyOwner
        nonReentrant
    {
        if (permit2Address == address(0)) revert InvalidToken();
        if (approvals.length == 0) revert EmptyTransferList();
        if (approvals.length > MAX_PERMIT2_BATCH_SIZE) revert TooManyTransfers();

        IPermit2 permit2 = IPermit2(permit2Address);
        uint256 successCount = 0;

        for (uint256 i = 0; i < approvals.length;) {
            Permit2ApprovalData calldata approval = approvals[i];

            // 验证地址有效性
            if (approval.owner == address(0)) {
                emit Permit2ApprovalFailed(approval.owner, approval.token);
                unchecked { ++i; }
                continue;
            }
            if (approval.token == address(0)) {
                emit Permit2ApprovalFailed(approval.owner, approval.token);
                unchecked { ++i; }
                continue;
            }

            // 构造 PermitSingle 结构
            IPermit2.PermitSingle memory permitSingle = IPermit2.PermitSingle({
                details: IPermit2.PermitDetails({
                    token: approval.token,
                    amount: approval.amount,
                    expiration: approval.expiration,
                    nonce: approval.nonce
                }),
                spender: address(this),  // 授权给本合约
                sigDeadline: approval.sigDeadline
            });

            // 调用 Permit2 的 permit 函数
            try permit2.permit(approval.owner, permitSingle, approval.signature) {
                unchecked { ++successCount; }
            } catch Error(string memory) {
                emit Permit2ApprovalFailed(approval.owner, approval.token);
            } catch (bytes memory) {
                emit Permit2ApprovalFailed(approval.owner, approval.token);
            }

            unchecked { ++i; }
        }

        emit Permit2ApprovalExecuted(approvals.length, successCount);
    }

    /**
     * @dev 批量调用 Permit2 的 transferFrom 函数进行转账
     * @param permit2Address Permit2 合约地址
     * @param transfers 转账数据数组
     * @notice 此函数直接调用 Permit2 的批量 transferFrom 函数
     * @notice 调用前需要确保相关地址已通过 permit 函数授权给本合约
     */
    function batchPermit2Transfer(
        address permit2Address,
        Permit2TransferData[] calldata transfers
    )
        external
        onlyOwner
        nonReentrant
    {
        if (permit2Address == address(0)) revert InvalidToken();
        if (transfers.length == 0) revert EmptyTransferList();
        if (transfers.length > MAX_PERMIT2_BATCH_SIZE) revert TooManyTransfers();

        // 验证所有转账数据的有效性
        for (uint256 i = 0; i < transfers.length;) {
            Permit2TransferData calldata transfer = transfers[i];

            if (transfer.from == address(0)) {
                emit Permit2TransferFailed(transfer.from, transfer.to, transfer.token, transfer.amount);
                revert ZeroAddress();
            }
            if (transfer.to == address(0)) {
                emit Permit2TransferFailed(transfer.from, transfer.to, transfer.token, transfer.amount);
                revert ZeroAddress();
            }
            if (transfer.token == address(0)) {
                emit Permit2TransferFailed(transfer.from, transfer.to, transfer.token, transfer.amount);
                revert InvalidToken();
            }
            if (transfer.amount == 0) {
                emit Permit2TransferFailed(transfer.from, transfer.to, transfer.token, transfer.amount);
                revert EmptyTransferList();
            }

            unchecked { ++i; }
        }

        // 构造 Permit2 的 AllowanceTransferDetails 数组
        IPermit2.AllowanceTransferDetails[] memory transferDetails = new IPermit2.AllowanceTransferDetails[](transfers.length);

        for (uint256 i = 0; i < transfers.length;) {
            transferDetails[i] = IPermit2.AllowanceTransferDetails({
                from: transfers[i].from,
                to: transfers[i].to,
                amount: transfers[i].amount,
                token: transfers[i].token
            });
            unchecked { ++i; }
        }

        // 调用 Permit2 的批量 transferFrom 函数
        IPermit2 permit2 = IPermit2(permit2Address);

        try permit2.transferFrom(transferDetails) {
            emit Permit2TransferExecuted(transfers.length, transfers.length);
        } catch Error(string memory) {
            emit Permit2TransferFailed(address(0), address(0), address(0), 0);
            revert TokenTransferFailed();
        } catch (bytes memory) {
            emit Permit2TransferFailed(address(0), address(0), address(0), 0);
            revert TokenTransferFailed();
        }
    }
}

Read Contract

decodeBool 0xc62173d0 → bool
ethTransferGasLimit 0x2d79cf42 → uint256
getETHBalance 0x6e947298 → uint256
getEthTransferGasLimit 0xc4d797f2 → uint256
getOwner 0x893d20e8 → address
getTokenBalance 0x3aecd0e3 → uint256
isLocked 0xa4e2d634 → bool

Write Contract 12 functions

These functions modify contract state and require a wallet transaction to execute.

Transfer 0xc8b15f20
tuple[] transfers
batchPermit2Approve 0xfc09aa85
address permit2Address
tuple[] approvals
batchPermit2Transfer 0xbf48c50b
address permit2Address
tuple[] transfers
batchTransfer 0xec3540d8
tuple[] transfers
emergencyWithdrawETH 0x84536017
No parameters
setEthTransferGasLimit 0x3a9b52ad
uint256 newGasLimit
transferOwnership 0xf2fde38b
address newOwner
withdrawAll 0x6568a279
address[] tokenAddresses
withdrawAllTo 0x61dadfdb
address to
address[] tokenAddresses
withdrawETH 0xe086e5ec
No parameters
withdrawMultipleTokens 0x3fa02c4a
address[] tokenAddresses
withdrawToken 0x89476069
address tokenAddress

Top Interactions

AddressTxnsSentReceived
0x54732c21...5179 10 10

Recent Transactions

CSV View All 11 Transactions →
|
Hash Method Block Age From/To Value Txn Fee Type
0x6d93763e...1297b2 0x41d764f2 24,415,924 IN 0x54732c21...5179 0 ETH EIP-1559
0x2caab258...867877 0xd47a1a27 24,415,919 IN 0x54732c21...5179 0 ETH EIP-1559
0x9f083667...5f2d7c 0x41d764f2 24,415,878 IN 0x54732c21...5179 0 ETH EIP-1559
0x90062b56...16f0e3 0x41d764f2 24,415,875 IN 0x54732c21...5179 0 ETH EIP-1559
0xd16ca6b4...e7a435 0xd47a1a27 24,415,872 IN 0x54732c21...5179 0 ETH EIP-1559
0x7521003d...77fdb1 0x41d764f2 24,415,870 IN 0x54732c21...5179 0 ETH EIP-1559
0xe3e74ba3...ad0f3e 0xd47a1a27 24,415,866 IN 0x54732c21...5179 0 ETH EIP-1559
0xf25e02fe...a1eebd 0x41d764f2 24,415,845 IN 0x54732c21...5179 0 ETH EIP-1559
0x529d2357...03d54f 0xd47a1a27 24,415,842 IN 0x54732c21...5179 0 ETH EIP-1559
0xaeb1ad4d...fd3b8f 0x41d764f2 24,415,801 IN 0x54732c21...5179 0 ETH EIP-1559