Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x62D459252db23F928A7074b32C8d6161596E2670
Balance 0.015952 ETH
Nonce 1
Code Size 12537 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

12537 bytes
0x6080604052600436106100fe5760003560e01c80638279c7db11610095578063ac8a584a11610064578063ac8a584a146102ef578063be4b177214610318578063f2fde38b14610341578063fc6f94681461036a578063ff53f05b14610395576100fe565b80638279c7db14610249578063896f01711461027257806389ff1f5b1461029b5780638da5cb5b146102c4576100fe565b80633c00a36c116100d15780633c00a36c146101b0578063572b6c05146101d957806370bbcbf514610216578063715018a614610232576100fe565b806313e7c9d81461010357806316fed3e2146101405780632c1e816d1461016b57806338b24c2a14610194575b600080fd5b34801561010f57600080fd5b5061012a60048036038101906101259190611dd8565b6103be565b6040516101379190611e20565b60405180910390f35b34801561014c57600080fd5b506101556103de565b6040516101629190611e4a565b60405180910390f35b34801561017757600080fd5b50610192600480360381019061018d9190611dd8565b610404565b005b6101ae60048036038101906101a9919061200d565b6104c2565b005b3480156101bc57600080fd5b506101d760048036038101906101d2919061210a565b610624565b005b3480156101e557600080fd5b5061020060048036038101906101fb9190611dd8565b610896565b60405161020d9190611e20565b60405180910390f35b610230600480360381019061022b9190612337565b6108ee565b005b34801561023e57600080fd5b50610247610bb0565b005b34801561025557600080fd5b50610270600480360381019061026b9190611dd8565b610bc4565b005b34801561027e57600080fd5b5061029960048036038101906102949190611dd8565b610c82565b005b3480156102a757600080fd5b506102c260048036038101906102bd9190612393565b610de4565b005b3480156102d057600080fd5b506102d961113f565b6040516102e69190611e4a565b60405180910390f35b3480156102fb57600080fd5b5061031660048036038101906103119190611dd8565b611168565b005b34801561032457600080fd5b5061033f600480360381019061033a9190612416565b6112c9565b005b34801561034d57600080fd5b5061036860048036038101906103639190611dd8565b6115aa565b005b34801561037657600080fd5b5061037f61162e565b60405161038c9190611e4a565b60405180910390f35b3480156103a157600080fd5b506103bc60048036038101906103b79190612456565b611654565b005b60036020528060005260406000206000915054906101000a900460ff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61040c611889565b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561047d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610474906125d9565b60405180910390fd5b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60003411610505576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104fc90612645565b60405180910390fd5b600061050f611907565b73ffffffffffffffffffffffffffffffffffffffff16311015610567576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161055e906126b1565b60405180910390fd5b80156105d757600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f193505050501580156105d5573d6000803e3d6000fd5b505b7fa97c286dc3d1bc2b6a7ab9066b0ee05b9b7b8539bd18b1004e0911132fede2aa8686868634874288604051610614989796959493929190612757565b60405180910390a1505050505050565b60036000610630611907565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166106b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ae9061283d565b60405180910390fd5b600081116106fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106f1906128a9565b60405180910390fd5b4781111561073d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073490612915565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156107cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107c690612981565b60405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610837573d6000803e3d6000fd5b507f95f34ba6e14773d4f8c50f4f6c39fbc2f47dfba1bb026c1a9a1b17bc534b5cec600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168260405161088b9291906129a1565b60405180910390a150565b60007f00000000000000000000000084a0856b038eaad1cc7e297cf34a7e72685a869373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b60003411610931576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161092890612645565b60405180910390fd5b600061093b611907565b73ffffffffffffffffffffffffffffffffffffffff16311015610993576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098a906126b1565b60405180910390fd5b6000805b83518110156109df578381815181106109b3576109b26129ca565b5b602002602001015160800151826109ca9190612a28565b915080806109d790612a7e565b915050610997565b50803414610a22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1990612b39565b60405180910390fd5b8115610a9257600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610a90573d6000803e3d6000fd5b505b60005b8351811015610baa577fa97c286dc3d1bc2b6a7ab9066b0ee05b9b7b8539bd18b1004e0911132fede2aa848281518110610ad257610ad16129ca565b5b602002602001015160000151858381518110610af157610af06129ca565b5b602002602001015160200151868481518110610b1057610b0f6129ca565b5b602002602001015160400151878581518110610b2f57610b2e6129ca565b5b602002602001015160600151888681518110610b4e57610b4d6129ca565b5b602002602001015160800151898781518110610b6d57610b6c6129ca565b5b602002602001015160a00151428a604051610b8f989796959493929190612757565b60405180910390a18080610ba290612a7e565b915050610a95565b50505050565b610bb8611889565b610bc26000611916565b565b610bcc611889565b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c34906125d9565b60405180910390fd5b81600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b610c8a611889565b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610cfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf2906125d9565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610d88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7f90612ba5565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000831015610e28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1f90612645565b60405180910390fd5b6000805b8551811015610e7457858181518110610e4857610e476129ca565b5b60200260200101516080015182610e5f9190612a28565b91508080610e6c90612a7e565b915050610e2c565b50808414610eb7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eae90612c37565b60405180910390fd5b838273ffffffffffffffffffffffffffffffffffffffff166370a08231610edc611907565b6040518263ffffffff1660e01b8152600401610ef89190611e4a565b60206040518083038186803b158015610f1057600080fd5b505afa158015610f24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f489190612c6c565b1015610f89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f80906126b1565b60405180910390fd5b8215610fea57610fe5610f9a611907565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868573ffffffffffffffffffffffffffffffffffffffff166119da909392919063ffffffff16565b61101f565b61101e610ff5611907565b30868573ffffffffffffffffffffffffffffffffffffffff166119da909392919063ffffffff16565b5b60005b8551811015611137577ffc62bc9478e40c66fb078efa7c02474d4e2abfa47a49ad8d4133355206b6064386828151811061105f5761105e6129ca565b5b60200260200101516000015187838151811061107e5761107d6129ca565b5b60200260200101516020015188848151811061109d5761109c6129ca565b5b6020026020010151604001518985815181106110bc576110bb6129ca565b5b6020026020010151606001518a86815181106110db576110da6129ca565b5b6020026020010151608001518b87815181106110fa576110f96129ca565b5b602002602001015160a00151428b60405161111c989796959493929190612757565b60405180910390a1808061112f90612a7e565b915050611022565b505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611170611889565b80600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156111e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d8906125d9565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661126d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126490612ce5565b60405180910390fd5b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600360006112d5611907565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661135c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113539061283d565b60405180910390fd5b6000821161139f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611396906128a9565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016113d89190611e4a565b60206040518083038186803b1580156113f057600080fd5b505afa158015611404573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114289190612c6c565b82111561146a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161146190612915565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156114fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f390612981565b60405180910390fd5b611549600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838373ffffffffffffffffffffffffffffffffffffffff16611a639092919063ffffffff16565b7fc7de2d139afb8c4257b3fac58f791fb657180f2f86753ed057e0c3a404f705a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838360405161159e93929190612d05565b60405180910390a15050565b6115b2611889565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611622576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161990612dae565b60405180910390fd5b61162b81611916565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000841015611698576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168f90612645565b60405180910390fd5b838373ffffffffffffffffffffffffffffffffffffffff166370a082316116bd611907565b6040518263ffffffff1660e01b81526004016116d99190611e4a565b60206040518083038186803b1580156116f157600080fd5b505afa158015611705573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117299190612c6c565b101561176a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611761906126b1565b60405180910390fd5b80156117cb576117c661177b611907565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868673ffffffffffffffffffffffffffffffffffffffff166119da909392919063ffffffff16565b611800565b6117ff6117d6611907565b30868673ffffffffffffffffffffffffffffffffffffffff166119da909392919063ffffffff16565b5b7ffc62bc9478e40c66fb078efa7c02474d4e2abfa47a49ad8d4133355206b60643888888888887428860405161183d989796959493929190612757565b60405180910390a15050505050505050565b600061185a33610896565b1561186e57601436033560601c905061187d565b611876611881565b905061187e565b5b90565b600033905090565b611891611907565b73ffffffffffffffffffffffffffffffffffffffff166118af61113f565b73ffffffffffffffffffffffffffffffffffffffff1614611905576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118fc90612e1a565b60405180910390fd5b565b600061191161184f565b905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611a5d846323b872dd60e01b8585856040516024016119fb93929190612e3a565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ae9565b50505050565b611ae48363a9059cbb60e01b8484604051602401611a829291906129a1565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ae9565b505050565b6000611b4b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611bb09092919063ffffffff16565b9050600081511115611bab5780806020019051810190611b6b9190612e86565b611baa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba190612f25565b60405180910390fd5b5b505050565b6060611bbf8484600085611bc8565b90509392505050565b606082471015611c0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c0490612fb7565b60405180910390fd5b611c1685611cdc565b611c55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c4c90613023565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611c7e919061308a565b60006040518083038185875af1925050503d8060008114611cbb576040519150601f19603f3d011682016040523d82523d6000602084013e611cc0565b606091505b5091509150611cd0828286611cff565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315611d0f57829050611d5f565b600083511115611d225782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d5691906130a1565b60405180910390fd5b9392505050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611da582611d7a565b9050919050565b611db581611d9a565b8114611dc057600080fd5b50565b600081359050611dd281611dac565b92915050565b600060208284031215611dee57611ded611d70565b5b6000611dfc84828501611dc3565b91505092915050565b60008115159050919050565b611e1a81611e05565b82525050565b6000602082019050611e356000830184611e11565b92915050565b611e4481611d9a565b82525050565b6000602082019050611e5f6000830184611e3b565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611eb882611e6f565b810181811067ffffffffffffffff82111715611ed757611ed6611e80565b5b80604052505050565b6000611eea611d66565b9050611ef68282611eaf565b919050565b600067ffffffffffffffff821115611f1657611f15611e80565b5b611f1f82611e6f565b9050602081019050919050565b82818337600083830152505050565b6000611f4e611f4984611efb565b611ee0565b905082815260208101848484011115611f6a57611f69611e6a565b5b611f75848285611f2c565b509392505050565b600082601f830112611f9257611f91611e65565b5b8135611fa2848260208601611f3b565b91505092915050565b6000819050919050565b611fbe81611fab565b8114611fc957600080fd5b50565b600081359050611fdb81611fb5565b92915050565b611fea81611e05565b8114611ff557600080fd5b50565b60008135905061200781611fe1565b92915050565b60008060008060008060c0878903121561202a57612029611d70565b5b600087013567ffffffffffffffff81111561204857612047611d75565b5b61205489828a01611f7d565b965050602087013567ffffffffffffffff81111561207557612074611d75565b5b61208189828a01611f7d565b955050604087013567ffffffffffffffff8111156120a2576120a1611d75565b5b6120ae89828a01611f7d565b94505060606120bf89828a01611fcc565b935050608087013567ffffffffffffffff8111156120e0576120df611d75565b5b6120ec89828a01611f7d565b92505060a06120fd89828a01611ff8565b9150509295509295509295565b6000602082840312156121205761211f611d70565b5b600061212e84828501611fcc565b91505092915050565b600067ffffffffffffffff82111561215257612151611e80565b5b602082029050602081019050919050565b600080fd5b600080fd5b600080fd5b600060c0828403121561218857612187612168565b5b61219260c0611ee0565b9050600082013567ffffffffffffffff8111156121b2576121b161216d565b5b6121be84828501611f7d565b600083015250602082013567ffffffffffffffff8111156121e2576121e161216d565b5b6121ee84828501611f7d565b602083015250604082013567ffffffffffffffff8111156122125761221161216d565b5b61221e84828501611f7d565b604083015250606061223284828501611fcc565b606083015250608061224684828501611fcc565b60808301525060a082013567ffffffffffffffff81111561226a5761226961216d565b5b61227684828501611f7d565b60a08301525092915050565b600061229561229084612137565b611ee0565b905080838252602082019050602084028301858111156122b8576122b7612163565b5b835b818110156122ff57803567ffffffffffffffff8111156122dd576122dc611e65565b5b8086016122ea8982612172565b855260208501945050506020810190506122ba565b5050509392505050565b600082601f83011261231e5761231d611e65565b5b813561232e848260208601612282565b91505092915050565b6000806040838503121561234e5761234d611d70565b5b600083013567ffffffffffffffff81111561236c5761236b611d75565b5b61237885828601612309565b925050602061238985828601611ff8565b9150509250929050565b600080600080608085870312156123ad576123ac611d70565b5b600085013567ffffffffffffffff8111156123cb576123ca611d75565b5b6123d787828801612309565b94505060206123e887828801611fcc565b93505060406123f987828801611ff8565b925050606061240a87828801611dc3565b91505092959194509250565b6000806040838503121561242d5761242c611d70565b5b600061243b85828601611fcc565b925050602061244c85828601611dc3565b9150509250929050565b600080600080600080600080610100898b03121561247757612476611d70565b5b600089013567ffffffffffffffff81111561249557612494611d75565b5b6124a18b828c01611f7d565b985050602089013567ffffffffffffffff8111156124c2576124c1611d75565b5b6124ce8b828c01611f7d565b975050604089013567ffffffffffffffff8111156124ef576124ee611d75565b5b6124fb8b828c01611f7d565b965050606061250c8b828c01611fcc565b955050608061251d8b828c01611fcc565b94505060a061252e8b828c01611dc3565b93505060c089013567ffffffffffffffff81111561254f5761254e611d75565b5b61255b8b828c01611f7d565b92505060e061256c8b828c01611ff8565b9150509295985092959890939650565b600082825260208201905092915050565b7f46575f496e76616c696420616464726573730000000000000000000000000000600082015250565b60006125c360128361257c565b91506125ce8261258d565b602082019050919050565b600060208201905081810360008301526125f2816125b6565b9050919050565b7f46575f5472616e7366657220616d6f756e7420696e76616c6964000000000000600082015250565b600061262f601a8361257c565b915061263a826125f9565b602082019050919050565b6000602082019050818103600083015261265e81612622565b9050919050565b7f46575f496e73756666696369656e7420746f6b656e2062616c616e6365000000600082015250565b600061269b601d8361257c565b91506126a682612665565b602082019050919050565b600060208201905081810360008301526126ca8161268e565b9050919050565b600081519050919050565b60005b838110156126fa5780820151818401526020810190506126df565b83811115612709576000848401525b50505050565b600061271a826126d1565b612724818561257c565b93506127348185602086016126dc565b61273d81611e6f565b840191505092915050565b61275181611fab565b82525050565b6000610100820190508181036000830152612772818b61270f565b90508181036020830152612786818a61270f565b9050818103604083015261279a818961270f565b90506127a96060830188612748565b6127b66080830187612748565b81810360a08301526127c8818661270f565b90506127d760c0830185612748565b6127e460e0830184611e11565b9998505050505050505050565b7f46575f596f7520617265206e6f74204f70657261746f72000000000000000000600082015250565b600061282760178361257c565b9150612832826127f1565b602082019050919050565b600060208201905081810360008301526128568161281a565b9050919050565b7f46575f576974686472617720616d6f756e7420696e76616c6964000000000000600082015250565b6000612893601a8361257c565b915061289e8261285d565b602082019050919050565b600060208201905081810360008301526128c281612886565b9050919050565b7f46575f4e6f7420656e6f75676820616d6f756e7420746f207769746864726177600082015250565b60006128ff60208361257c565b915061290a826128c9565b602082019050919050565b6000602082019050818103600083015261292e816128f2565b9050919050565b7f46575f496e76616c69642061646d696e20616464726573730000000000000000600082015250565b600061296b60188361257c565b915061297682612935565b602082019050919050565b6000602082019050818103600083015261299a8161295e565b9050919050565b60006040820190506129b66000830185611e3b565b6129c36020830184612748565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612a3382611fab565b9150612a3e83611fab565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612a7357612a726129f9565b5b828201905092915050565b6000612a8982611fab565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612abc57612abb6129f9565b5b600182019050919050565b7f46575f53756d206f662063617274206e6f74206d617463682073656e64206e6160008201527f7469766520616d6f756e74000000000000000000000000000000000000000000602082015250565b6000612b23602b8361257c565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b7f46575f4f70657261746f7220616c726561647920657869737473000000000000600082015250565b6000612b8f601a8361257c565b9150612b9a82612b59565b602082019050919050565b60006020820190508181036000830152612bbe81612b82565b9050919050565b7f46575f53756d206f662063617274206e6f74206d617463682073656e6420746f60008201527f6b656e20616d6f756e7400000000000000000000000000000000000000000000602082015250565b6000612c21602a8361257c565b9150612c2c82612bc5565b604082019050919050565b60006020820190508181036000830152612c5081612c14565b9050919050565b600081519050612c6681611fb5565b92915050565b600060208284031215612c8257612c81611d70565b5b6000612c9084828501612c57565b91505092915050565b7f46575f4f70657261746f72206e6f742073657475702079657400000000000000600082015250565b6000612ccf60198361257c565b9150612cda82612c99565b602082019050919050565b60006020820190508181036000830152612cfe81612cc2565b9050919050565b6000606082019050612d1a6000830186611e3b565b612d276020830185612748565b612d346040830184611e3b565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612d9860268361257c565b9150612da382612d3c565b604082019050919050565b60006020820190508181036000830152612dc781612d8b565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612e0460208361257c565b9150612e0f82612dce565b602082019050919050565b60006020820190508181036000830152612e3381612df7565b9050919050565b6000606082019050612e4f6000830186611e3b565b612e5c6020830185611e3b565b612e696040830184612748565b949350505050565b600081519050612e8081611fe1565b92915050565b600060208284031215612e9c57612e9b611d70565b5b6000612eaa84828501612e71565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000612f0f602a8361257c565b9150612f1a82612eb3565b604082019050919050565b60006020820190508181036000830152612f3e81612f02565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000612fa160268361257c565b9150612fac82612f45565b604082019050919050565b60006020820190508181036000830152612fd081612f94565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b600061300d601d8361257c565b915061301882612fd7565b602082019050919050565b6000602082019050818103600083015261303c81613000565b9050919050565b600081519050919050565b600081905092915050565b600061306482613043565b61306e818561304e565b935061307e8185602086016126dc565b80840191505092915050565b60006130968284613059565b915081905092915050565b600060208201905081810360008301526130bb818461270f565b90509291505056fea2646970667358221220ce4a8b53ae754bc95748cb81e726fd9156b8efeb84286d66c97be94d4a40f17f64736f6c63430008090033

Verified Source Code Full Match

Compiler: v0.8.9+commit.e5eed63a EVM: london Optimization: No
IERC20.sol 82 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}
SafeMath.sol 227 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}
ERC20.sol 383 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}
IERC20Metadata.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}
Ownable.sol 83 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
ERC2771Context.sol 43 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (metatx/ERC2771Context.sol)

pragma solidity ^0.8.9;

import "../utils/Context.sol";

/**
 * @dev Context variant with ERC2771 support.
 */
abstract contract ERC2771Context is Context {
    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
    address private immutable _trustedForwarder;

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor(address trustedForwarder) {
        _trustedForwarder = trustedForwarder;
    }

    function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
        return forwarder == _trustedForwarder;
    }

    function _msgSender() internal view virtual override returns (address sender) {
        if (isTrustedForwarder(msg.sender)) {
            // The assembly code is more direct than the Solidity version using `abi.decode`.
            /// @solidity memory-safe-assembly
            assembly {
                sender := shr(96, calldataload(sub(calldatasize(), 20)))
            }
        } else {
            return super._msgSender();
        }
    }

    function _msgData() internal view virtual override returns (bytes calldata) {
        if (isTrustedForwarder(msg.sender)) {
            return msg.data[:msg.data.length - 20];
        } else {
            return super._msgData();
        }
    }
}
SafeERC20.sol 116 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}
Address.sol 222 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}
draft-IERC20Permit.sol 60 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}
PurchaseGiftcard.sol 322 lines
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/metatx/ERC2771Context.sol";

contract PurchaseGiftcard is ERC2771Context, Ownable {
  using SafeMath for uint256;
  using SafeERC20 for IERC20;

  struct CartItem {
    string _voucherID;
    string _fromFiatID;
    string _toCryptoID;
    uint256 _fiatDenomination;
    uint256 _cryptoDenomination;
    string _orderID;
  }

  address public adminAddress;
  address public receiverAddress;
  mapping(address => bool) public operators;

  event PurchaseByCurrency(
    string voucherID,
    string fromFiatID,
    string toCryptoID,
    uint256 fiatDenomination,
    uint256 cryptoAmount,
    string orderID,
    uint256 purchaseTime,
    bool isSwap
  );
  event PurchaseByToken(
    string voucherID,
    string fromFiatID,
    string toCryptoID,
    uint256 fiatDenomination,
    uint256 cryptoAmount,
    string orderID,
    uint256 purchaseTime,
    bool isSwap
  );
  event WithdrawCurrency(address adminAddress, uint256 currencyAmount);
  event WithdrawToken(
    address adminAddress,
    uint256 tokenAmount,
    address tokenAddress
  );

  constructor(address _trustedForwarder) ERC2771Context(_trustedForwarder) {
    adminAddress = _msgSender();
    receiverAddress = _msgSender();
  }

  /* ****************** */
  /*   Internal View    */
  /* ****************** */

  function _msgSender()
    internal
    view
    virtual
    override(Context, ERC2771Context)
    returns (address)
  {
    return ERC2771Context._msgSender();
  }

  function _msgData()
    internal
    view
    virtual
    override(Context, ERC2771Context)
    returns (bytes calldata)
  {
    return ERC2771Context._msgData();
  }

  // For owner
  function setupOperator(address operatorAddress)
    external
    onlyOwner
    isValidAddress(operatorAddress)
  {
    require(!operators[operatorAddress], "FW_Operator already exists");
    operators[operatorAddress] = true;
  }

  function removeOperator(address operatorAddress)
    external
    onlyOwner
    isValidAddress(operatorAddress)
  {
    require(operators[operatorAddress], "FW_Operator not setup yet");
    operators[operatorAddress] = false;
  }

  function setAdminAddress(address _adminAddress)
    external
    onlyOwner
    isValidAddress(_adminAddress)
  {
    adminAddress = _adminAddress;
  }

  function setReceiverAddress(address _receiverAddress)
    external
    onlyOwner
    isValidAddress(_receiverAddress)
  {
    receiverAddress = _receiverAddress;
  }

  // For operator
  function withdrawCurrency(uint256 currencyAmount) external onlyOperater {
    require(currencyAmount > 0, "FW_Withdraw amount invalid");

    require(
      currencyAmount <= address(this).balance,
      "FW_Not enough amount to withdraw"
    );

    require(adminAddress != address(0), "FW_Invalid admin address");

    payable(adminAddress).transfer(currencyAmount);

    emit WithdrawCurrency(adminAddress, currencyAmount);
  }

  function withdrawToken(uint256 tokenAmount, address tokenAddress)
    external
    onlyOperater
  {
    require(tokenAmount > 0, "FW_Withdraw amount invalid");

    require(
      tokenAmount <= IERC20(tokenAddress).balanceOf(address(this)),
      "FW_Not enough amount to withdraw"
    );

    require(adminAddress != address(0), "FW_Invalid admin address");

    IERC20(tokenAddress).safeTransfer(adminAddress, tokenAmount);

    emit WithdrawToken(adminAddress, tokenAmount, tokenAddress);
  }

  function purchaseByCurrency(
    string memory _voucherID,
    string memory _fromFiatID,
    string memory _toCryptoID,
    uint256 _fiatDenomination,
    string memory _orderID,
    bool _isSwap
  ) external payable {
    require(msg.value > 0, "FW_Transfer amount invalid");

    require(_msgSender().balance >= 0, "FW_Insufficient token balance");

    if (_isSwap) {
      payable(receiverAddress).transfer(msg.value);
    }

    emit PurchaseByCurrency(
      _voucherID,
      _fromFiatID,
      _toCryptoID,
      _fiatDenomination,
      msg.value,
      _orderID,
      block.timestamp,
      _isSwap
    );
  }

  function purchaseMultipleByCurrency(
    CartItem[] memory _cartItems,
    bool _isSwap
  ) external payable {
    require(msg.value > 0, "FW_Transfer amount invalid");

    require(_msgSender().balance >= 0, "FW_Insufficient token balance");

    uint256 cartSum = 0;

    for (uint256 i = 0; i < _cartItems.length; i++) {
      cartSum = cartSum + _cartItems[i]._cryptoDenomination;
    }

    require(
      msg.value == cartSum,
      "FW_Sum of cart not match send native amount"
    );

    if (_isSwap) {
      payable(receiverAddress).transfer(cartSum);
    }

    for (uint256 i = 0; i < _cartItems.length; i++) {
      emit PurchaseByCurrency(
        _cartItems[i]._voucherID,
        _cartItems[i]._fromFiatID,
        _cartItems[i]._toCryptoID,
        _cartItems[i]._fiatDenomination,
        _cartItems[i]._cryptoDenomination,
        _cartItems[i]._orderID,
        block.timestamp,
        _isSwap
      );
    }
  }

  function purchaseByToken(
    string memory _voucherID,
    string memory _fromFiatID,
    string memory _toCryptoID,
    uint256 _fiatDenomination,
    uint256 _cryptoAmount,
    address token,
    string memory _orderID,
    bool _isSwap
  ) external {
    require(_cryptoAmount >= 0, "FW_Transfer amount invalid");

    require(
      IERC20(token).balanceOf(_msgSender()) >= _cryptoAmount,
      "FW_Insufficient token balance"
    );

    if (_isSwap) {
      IERC20(token).safeTransferFrom(
        _msgSender(),
        receiverAddress,
        _cryptoAmount
      );
    } else {
      IERC20(token).safeTransferFrom(
        _msgSender(),
        address(this),
        _cryptoAmount
      );
    }

    emit PurchaseByToken(
      _voucherID,
      _fromFiatID,
      _toCryptoID,
      _fiatDenomination,
      _cryptoAmount,
      _orderID,
      block.timestamp,
      _isSwap
    );
  }

  function purchaseMultipleByToken(
    CartItem[] memory _cartItems,
    uint256 _cryptoAmount,
    bool _isSwap,
    address token
  ) external {
    require(_cryptoAmount >= 0, "FW_Transfer amount invalid");

    uint256 cartSum = 0;

    for (uint256 i = 0; i < _cartItems.length; i++) {
      cartSum = cartSum + _cartItems[i]._cryptoDenomination;
    }

    require(
      _cryptoAmount == cartSum,
      "FW_Sum of cart not match send token amount"
    );

    require(
      IERC20(token).balanceOf(_msgSender()) >= _cryptoAmount,
      "FW_Insufficient token balance"
    );

    if (_isSwap) {
      IERC20(token).safeTransferFrom(
        _msgSender(),
        receiverAddress,
        _cryptoAmount
      );
    } else {
      IERC20(token).safeTransferFrom(
        _msgSender(),
        address(this),
        _cryptoAmount
      );
    }

    for (uint256 i = 0; i < _cartItems.length; i++) {
      emit PurchaseByToken(
        _cartItems[i]._voucherID,
        _cartItems[i]._fromFiatID,
        _cartItems[i]._toCryptoID,
        _cartItems[i]._fiatDenomination,
        _cartItems[i]._cryptoDenomination,
        _cartItems[i]._orderID,
        block.timestamp,
        _isSwap
      );
    }
  }

  modifier onlyOperater() {
    require(operators[_msgSender()], "FW_You are not Operator");
    _;
  }

  modifier isValidAddress(address _address) {
    require(_address != address(0), "FW_Invalid address");
    _;
  }
}

Read Contract

adminAddress 0xfc6f9468 → address
isTrustedForwarder 0x572b6c05 → bool
operators 0x13e7c9d8 → bool
owner 0x8da5cb5b → address
receiverAddress 0x16fed3e2 → address

Write Contract 12 functions

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

purchaseByCurrency 0x38b24c2a
string _voucherID
string _fromFiatID
string _toCryptoID
uint256 _fiatDenomination
string _orderID
bool _isSwap
purchaseByToken 0xff53f05b
string _voucherID
string _fromFiatID
string _toCryptoID
uint256 _fiatDenomination
uint256 _cryptoAmount
address token
string _orderID
bool _isSwap
purchaseMultipleByCurrency 0x3a6700de
tuple[] _cartItems
bool _isSwap
purchaseMultipleByToken 0xf00e48aa
tuple[] _cartItems
uint256 _cryptoAmount
bool _isSwap
address token
removeOperator 0xac8a584a
address operatorAddress
renounceOwnership 0x715018a6
No parameters
setAdminAddress 0x2c1e816d
address _adminAddress
setReceiverAddress 0x8279c7db
address _receiverAddress
setupOperator 0x896f0171
address operatorAddress
transferOwnership 0xf2fde38b
address newOwner
withdrawCurrency 0x3c00a36c
uint256 currencyAmount
withdrawToken 0xbe4b1772
uint256 tokenAmount
address tokenAddress

Recent Transactions

No transactions found for this address