Address Contract Partially Verified
Address
0x9973ee0bb7F10988F23eCfFF54dC654A7F173e2c
Balance
0 ETH
Nonce
1
Code Size
21520 bytes
Creator
0xdDb4A874...1d3C at tx 0x792fcfb9...c96e2e
Indexed Transactions
0
Contract Bytecode
21520 bytes
0x608060405234801561000f575f80fd5b50600436106101ee575f3560e01c806370a082311161010d578063a136e2e9116100a0578063cf9dfe671161006f578063cf9dfe67146105fb578063d547741f14610619578063dd62ed3e14610635578063fb66da2c14610665576101ee565b8063a136e2e914610573578063a217fddf14610591578063a9059cbb146105af578063cda6b847146105df576101ee565b806394c0b71b116100dc57806394c0b71b146104d957806394d74d8f146104f557806395d89b411461052557806397a909c514610543576101ee565b806370a082311461042a57806378238c371461045a5780637d2597bc1461047657806391d14854146104a9576101ee565b806324d7806c1161018557806344df8e701161015457806344df8e701461039c5780634cfc302a146103a65780634fa4544f146103dc5780636548ec3c146103fa576101ee565b806324d7806c146103165780632f2ff15d14610346578063313ce5671461036257806336568abe14610380576101ee565b80631394de35116101c15780631394de351461027a57806318160ddd1461029857806323b872dd146102b6578063248a9ca3146102e6576101ee565b806301ffc9a7146101f257806306fdde0314610222578063095ea7b3146102405780631249c58b14610270575b5f80fd5b61020c60048036038101906102079190613d24565b610695565b6040516102199190613d69565b60405180910390f35b61022a61070e565b6040516102379190613e0c565b60405180910390f35b61025a60048036038101906102559190613eb9565b61079e565b6040516102679190613d69565b60405180910390f35b6102786107c0565b005b6102826107fb565b60405161028f9190613fae565b60405180910390f35b6102a061097b565b6040516102ad9190613fdd565b60405180910390f35b6102d060048036038101906102cb9190613ff6565b610984565b6040516102dd9190613d69565b60405180910390f35b61030060048036038101906102fb9190614079565b6109e5565b60405161030d91906140b3565b60405180910390f35b610330600480360381019061032b91906140cc565b610a02565b60405161033d9190613d69565b60405180910390f35b610360600480360381019061035b91906140f7565b610a16565b005b61036a610a2d565b6040516103779190614150565b60405180910390f35b61039a600480360381019061039591906140f7565b610a35565b005b6103a4610a39565b005b6103c060048036038101906103bb9190614169565b610a74565b6040516103d397969594939291906141a3565b60405180910390f35b6103e4610c04565b6040516103f19190613fdd565b60405180910390f35b610414600480360381019061040f91906140cc565b610c12565b6040516104219190613fdd565b60405180910390f35b610444600480360381019061043f91906140cc565b610fd8565b6040516104519190613fdd565b60405180910390f35b610474600480360381019061046f91906140cc565b61101d565b005b610490600480360381019061048b91906140cc565b6111a5565b6040516104a094939291906142c7565b60405180910390f35b6104c360048036038101906104be91906140f7565b611436565b6040516104d09190613d69565b60405180910390f35b6104f360048036038101906104ee9190614482565b61149a565b005b61050f600480360381019061050a919061456d565b611b45565b60405161051c9190613fdd565b60405180910390f35b61052d61250c565b60405161053a9190613e0c565b60405180910390f35b61055d600480360381019061055891906140cc565b61259c565b60405161056a9190613fdd565b60405180910390f35b61057b6129d0565b6040516105889190613fdd565b60405180910390f35b6105996129d9565b6040516105a691906140b3565b60405180910390f35b6105c960048036038101906105c49190613eb9565b6129df565b6040516105d69190613d69565b60405180910390f35b6105f960048036038101906105f49190614169565b612a45565b005b610603612afd565b6040516106109190613fae565b60405180910390f35b610633600480360381019061062e91906140f7565b612b88565b005b61064f600480360381019061064a9190614598565b612b9f565b60405161065c9190613fdd565b60405180910390f35b61067f600480360381019061067a91906140cc565b612c21565b60405161068c9190613fdd565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610707575061070682613055565b5b9050919050565b60606003805461071d90614603565b80601f016020809104026020016040519081016040528092919081815260200182805461074990614603565b80156107945780601f1061076b57610100808354040283529160200191610794565b820191905f5260205f20905b81548152906001019060200180831161077757829003601f168201915b5050505050905090565b5f806107a86130be565b90506107b58185856130c5565b600191505092915050565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f2906146a3565b60405180910390fd5b60606108056130d7565b67ffffffffffffffff81111561081e5761081d614346565b5b60405190808252806020026020018201604052801561084c5781602001602082028036833780820191505090505b5090505f805b600980549050811015610976575f73ffffffffffffffffffffffffffffffffffffffff166009828154811061088a576108896146c1565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461096357600981815481106108e1576108e06146c1565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff168383806109159061471b565b945081518110610928576109276146c1565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b808061096e9061471b565b915050610852565b505090565b5f600254905090565b5f816109908585613183565b10156109d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109c8906147d2565b60405180910390fd5b6109dc848484613472565b90509392505050565b5f60055f8381526020019081526020015f20600101549050919050565b5f610a0f5f801b83611436565b9050919050565b610a1f826109e5565b610a28816134a0565b505050565b5f6008905090565b5050565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6b90614860565b60405180910390fd5b5f805f805f805f600b548810610abf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ab6906148ee565b60405180910390fd5b600a5f8981526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169650600a5f8981526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169550600a5f8981526020019081526020015f20600201549450600a5f8981526020019081526020015f20600301549350600a5f8981526020019081526020015f206004015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169250600a5f8981526020019081526020015f206005015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169150600a5f8981526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919395979092949650565b5f610c0d6130d7565b905090565b5f610c1c336134b4565b610c5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c529061497c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610cc9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc090614a0a565b60405180910390fd5b5f600b541480610cfa57505f600a5f6001600b54610ce79190614a28565b81526020019081526020015f2060030154115b610d39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3090614acb565b60405180910390fd5b5f600b5490506001600b5f828254610d519190614ae9565b925050819055506040518060e001604052805f73ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff168152602001600281526020015f81526020013373ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff16815250600a5f8381526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020155606082015181600301556080820151816004015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a0820151816005015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060c0820151816006015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050503373ffffffffffffffffffffffffffffffffffffffff167f1856f2a9466fc9694120d85bbe5912e43f8dcac0e7444b633d37e9b8797edc4c600283604051610fc7929190614b5e565b60405180910390a280915050919050565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b611026336134b4565b611065576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105c9061497c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff1660065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146110f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110eb90614bf5565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611162576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161115990614c83565b60405180910390fd5b8060065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f806060805f93505f60085f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206040518060800160405290815f820154815260200160018201548152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160038201805480602002602001604051908101604052809291908181526020015f905b828210156112c5578382905f5260205f2090600202016040518060400160405290815f820154815260200160018201548152505081526020019060010190611282565b505050508152505090505f815f0151111561142e57805f015194508060200151935080606001515167ffffffffffffffff81111561130657611305614346565b5b6040519080825280602002602001820160405280156113345781602001602082028036833780820191505090505b50925080606001515167ffffffffffffffff81111561135657611355614346565b5b6040519080825280602002602001820160405280156113845781602001602082028036833780820191505090505b5091505f5b81606001515181101561142c57816060015181815181106113ad576113ac6146c1565b5b60200260200101515f01518482815181106113cb576113ca6146c1565b5b602002602001018181525050816060015181815181106113ee576113ed6146c1565b5b60200260200101516020015183828151811061140d5761140c6146c1565b5b60200260200101818152505080806114249061471b565b915050611389565b505b509193509193565b5f60055f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b6114a3336134b4565b6114e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114d99061497c565b60405180910390fd5b5f840361172e5760085f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8082015f9055600182015f9055600282015f6101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600382015f6115699190613c79565b50505f60078054905090505f5b81811015611727578673ffffffffffffffffffffffffffffffffffffffff16600782815481106115a9576115a86146c1565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036117145760078181548110611600576115ff6146c1565b5b905f5260205f20015f6101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560076001836116399190614a28565b8154811061164a576116496146c1565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660078281548110611686576116856146c1565b5b905f5260205f20015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060078054806116dd576116dc614ca1565b5b600190038181905f5260205f20015f6101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690559055611727565b808061171f9061471b565b915050611576565b5050611b3d565b8051825114611772576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176990614d64565b60405180910390fd5b5f805b83518110156117b957828181518110611791576117906146c1565b5b6020026020010151826117a49190614ae9565b915080806117b19061471b565b915050611775565b50848111156117fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f490614e18565b60405180910390fd5b8460085f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f01819055508360ff1660085f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600101819055508660085f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060085f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206003015f6119529190613c79565b5f5b8351811015611a335760085f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060030160405180604001604052808684815181106119bb576119ba6146c1565b5b602002602001015181526020018584815181106119db576119da6146c1565b5b6020026020010151815250908060018154018082558091505060019003905f5260205f2090600202015f909190919091505f820151815f01556020820151816001015550508080611a2b9061471b565b915050611954565b505f8060078054905090505f5b81811015611ad2578873ffffffffffffffffffffffffffffffffffffffff1660078281548110611a7357611a726146c1565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611abf5760019250611ad2565b8080611aca9061471b565b915050611a40565b5081611b3957600788908060018154018082558091505060019003905f5260205f20015f9091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050505b505050505050565b5f611b4f336134b4565b611b8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b859061497c565b60405180910390fd5b5f600b5411611bd2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bc990614ea6565b60405180910390fd5b5f6001600b54611be29190614a28565b90505f600b54118015611c0857505f600a5f8381526020019081526020015f2060030154145b611c47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3e90614f34565b60405180910390fd5b600a5f8281526020019081526020015f206004015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1603611ce8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cdf90614fc2565b60405180910390fd5b82156123e0576001600a5f8381526020019081526020015f206003018190555033600a5f8381526020019081526020015f206005015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505f600a5f8381526020019081526020015f206006015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600a5f8381526020019081526020015f206002015403611f3557611e065f801b600a5f8481526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166134c8565b506009600a5f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060018154018082558091505060019003905f5260205f20015f9091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600a5f8281526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fbc711a5bc58cc648fd036ed1db719e9c7c5fb92914031817f543568b9f936b6a83604051611f289190613fdd565b60405180910390a36123db565b6002600a5f8381526020019081526020015f20600201540361215157611f905f801b600a5f8481526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166135b2565b505f5b6009805490508110156120b357600a5f8381526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660098281548110611ffe57611ffd6146c1565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036120a0575f60098281548110612056576120556146c1565b5b905f5260205f20015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506120b3565b80806120ab9061471b565b915050611f93565b50600a5f8281526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f93a2f844485e30d143e0c7361eebf3f6ec34c4f4f55332eea2be8c70a0fe5ea0836040516121449190613fdd565b60405180910390a36123da565b6003600a5f8381526020019081526020015f2060020154036123d9576121ab5f801b600a5f8481526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166134c8565b506121eb5f801b600a5f8481526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166135b2565b505f5b60098054905081101561234057600a5f8381526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660098281548110612259576122586146c1565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361232d57600a5f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600982815481106122e3576122e26146c1565b5b905f5260205f20015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612340565b80806123389061471b565b9150506121ee565b50600a5f8281526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ffc8f4d09e96ba904a527fa1360c3d459aacd1f47bbb98e364a49dde5d9b1b0da836040516123d09190613fdd565b60405180910390a35b5b5b612503565b6002600a5f8381526020019081526020015f20600301819055505f600a5f8381526020019081526020015f206005015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555033600a5f8381526020019081526020015f206006015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167f9abb3b33111900360d220d1245bf87c952c1371f54d8cabc10407e50a9e9d26c600a5f8481526020019081526020015f2060020154836040516124fa929190614fe0565b60405180910390a25b80915050919050565b60606004805461251b90614603565b80601f016020809104026020016040519081016040528092919081815260200182805461254790614603565b80156125925780601f1061256957610100808354040283529160200191612592565b820191905f5260205f20905b81548152906001019060200180831161257557829003601f168201915b5050505050905090565b5f6125a6336134b4565b6125e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125dc9061497c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612653576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161264a90615077565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036126c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126b890615105565b60405180910390fd5b5f600b5414806126f257505f600a5f6001600b546126df9190614a28565b81526020019081526020015f2060030154115b612731576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161272890614acb565b60405180910390fd5b5f600b5490506001600b5f8282546127499190614ae9565b925050819055506040518060e001604052808473ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001600381526020015f81526020013373ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff16815250600a5f8381526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020155606082015181600301556080820151816004015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a0820151816005015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060c0820151816006015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050503373ffffffffffffffffffffffffffffffffffffffff167f1856f2a9466fc9694120d85bbe5912e43f8dcac0e7444b633d37e9b8797edc4c6003836040516129bf92919061515c565b60405180910390a280915050919050565b5f600b54905090565b5f801b81565b5f816129f26129ec6130be565b85613183565b1015612a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a2a906151f3565b60405180910390fd5b612a3d838361369c565b905092915050565b612a7060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16826129df565b5060065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166347e7ef2433836040518363ffffffff1660e01b8152600401612acd929190615211565b5f604051808303815f87803b158015612ae4575f80fd5b505af1158015612af6573d5f803e3d5ffd5b5050505050565b60606007805480602002602001604051908101604052809291908181526020018280548015612b7e57602002820191905f5260205f20905b815f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311612b35575b5050505050905090565b612b91826109e5565b612b9a816134a0565b505050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b5f612c2b336134b4565b612c6a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c619061497c565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612cd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ccf90614a0a565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612d46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d3d906152a8565b60405180910390fd5b5f600b541480612d7757505f600a5f6001600b54612d649190614a28565b81526020019081526020015f2060030154115b612db6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dad90614acb565b60405180910390fd5b5f600b5490506001600b5f828254612dce9190614ae9565b925050819055506040518060e001604052808473ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff168152602001600181526020015f81526020013373ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff16815250600a5f8381526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020155606082015181600301556080820151816004015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a0820151816005015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060c0820151816006015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050503373ffffffffffffffffffffffffffffffffffffffff167f1856f2a9466fc9694120d85bbe5912e43f8dcac0e7444b633d37e9b8797edc4c6001836040516130449291906152ff565b60405180910390a280915050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f33905090565b6130d283838360016136be565b505050565b5f805f90505f5b60098054905081101561317b575f73ffffffffffffffffffffffffffffffffffffffff1660098281548110613116576131156146c1565b5b905f5260205f20015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146131685781806131649061471b565b9250505b80806131739061471b565b9150506130de565b508091505090565b5f8061318e84610fd8565b90505f60085f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206040518060800160405290815f820154815260200160018201548152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160038201805480602002602001604051908101604052809291908181526020015f905b828210156132a8578382905f5260205f2090600202016040518060400160405290815f820154815260200160018201548152505081526020019060010190613265565b505050508152505090505f815f015114806132f257508373ffffffffffffffffffffffffffffffffffffffff16816040015173ffffffffffffffffffffffffffffffffffffffff16145b1561330157819250505061346c565b5f816040015173ffffffffffffffffffffffffffffffffffffffff166323fc91e4876040518263ffffffff1660e01b815260040161333f9190615326565b602060405180830381865afa15801561335a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061337e9190615353565b90505f818461338d9190614ae9565b90505f4290505f84606001515190505f5b8181101561344c5782866060015182815181106133be576133bd6146c1565b5b60200260200101515f0151111561343957856060015181815181106133e6576133e56146c1565b5b602002602001015160200151841015613408575f97505050505050505061346c565b8560600151818151811061341f5761341e6146c1565b5b602002602001015160200151846134369190614a28565b93505b80806134449061471b565b91505061339e565b508583106134625785965050505050505061346c565b8296505050505050505b92915050565b5f8061347c6130be565b905061348985828561388d565b61349485858561391f565b60019150509392505050565b6134b1816134ac6130be565b613a0f565b50565b5f6134c15f801b83611436565b9050919050565b5f6134d38383611436565b6135a857600160055f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506135456130be565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4600190506135ac565b5f90505b92915050565b5f6135bd8383611436565b15613692575f60055f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061362f6130be565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050613696565b5f90505b92915050565b5f806136a66130be565b90506136b381858561391f565b600191505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361372e575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016137259190615326565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361379e575f6040517f94280d620000000000000000000000000000000000000000000000000000000081526004016137959190615326565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015613887578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161387e9190613fdd565b60405180910390a35b50505050565b5f6138988484612b9f565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114613919578181101561390a578281836040517ffb8f41b20000000000000000000000000000000000000000000000000000000081526004016139019392919061537e565b60405180910390fd5b61391884848484035f6136be565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361398f575f6040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016139869190615326565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036139ff575f6040517fec442f050000000000000000000000000000000000000000000000000000000081526004016139f69190615326565b60405180910390fd5b613a0a838383613a60565b505050565b613a198282611436565b613a5c5780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401613a539291906153b3565b60405180910390fd5b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603613ab0578060025f828254613aa49190614ae9565b92505081905550613b7e565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015613b39578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401613b309392919061537e565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613bc5578060025f8282540392505081905550613c0f565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051613c6c9190613fdd565b60405180910390a3505050565b5080545f8255600202905f5260205f2090810190613c979190613c9a565b50565b5b80821115613cba575f8082015f9055600182015f905550600201613c9b565b5090565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613d0381613ccf565b8114613d0d575f80fd5b50565b5f81359050613d1e81613cfa565b92915050565b5f60208284031215613d3957613d38613cc7565b5b5f613d4684828501613d10565b91505092915050565b5f8115159050919050565b613d6381613d4f565b82525050565b5f602082019050613d7c5f830184613d5a565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015613db9578082015181840152602081019050613d9e565b5f8484015250505050565b5f601f19601f8301169050919050565b5f613dde82613d82565b613de88185613d8c565b9350613df8818560208601613d9c565b613e0181613dc4565b840191505092915050565b5f6020820190508181035f830152613e248184613dd4565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f613e5582613e2c565b9050919050565b613e6581613e4b565b8114613e6f575f80fd5b50565b5f81359050613e8081613e5c565b92915050565b5f819050919050565b613e9881613e86565b8114613ea2575f80fd5b50565b5f81359050613eb381613e8f565b92915050565b5f8060408385031215613ecf57613ece613cc7565b5b5f613edc85828601613e72565b9250506020613eed85828601613ea5565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b613f2981613e4b565b82525050565b5f613f3a8383613f20565b60208301905092915050565b5f602082019050919050565b5f613f5c82613ef7565b613f668185613f01565b9350613f7183613f11565b805f5b83811015613fa1578151613f888882613f2f565b9750613f9383613f46565b925050600181019050613f74565b5085935050505092915050565b5f6020820190508181035f830152613fc68184613f52565b905092915050565b613fd781613e86565b82525050565b5f602082019050613ff05f830184613fce565b92915050565b5f805f6060848603121561400d5761400c613cc7565b5b5f61401a86828701613e72565b935050602061402b86828701613e72565b925050604061403c86828701613ea5565b9150509250925092565b5f819050919050565b61405881614046565b8114614062575f80fd5b50565b5f813590506140738161404f565b92915050565b5f6020828403121561408e5761408d613cc7565b5b5f61409b84828501614065565b91505092915050565b6140ad81614046565b82525050565b5f6020820190506140c65f8301846140a4565b92915050565b5f602082840312156140e1576140e0613cc7565b5b5f6140ee84828501613e72565b91505092915050565b5f806040838503121561410d5761410c613cc7565b5b5f61411a85828601614065565b925050602061412b85828601613e72565b9150509250929050565b5f60ff82169050919050565b61414a81614135565b82525050565b5f6020820190506141635f830184614141565b92915050565b5f6020828403121561417e5761417d613cc7565b5b5f61418b84828501613ea5565b91505092915050565b61419d81613e4b565b82525050565b5f60e0820190506141b65f83018a614194565b6141c36020830189614194565b6141d06040830188613fce565b6141dd6060830187613fce565b6141ea6080830186614194565b6141f760a0830185614194565b61420460c0830184614194565b98975050505050505050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61424281613e86565b82525050565b5f6142538383614239565b60208301905092915050565b5f602082019050919050565b5f61427582614210565b61427f818561421a565b935061428a8361422a565b805f5b838110156142ba5781516142a18882614248565b97506142ac8361425f565b92505060018101905061428d565b5085935050505092915050565b5f6080820190506142da5f830187613fce565b6142e76020830186613fce565b81810360408301526142f9818561426b565b9050818103606083015261430d818461426b565b905095945050505050565b61432181614135565b811461432b575f80fd5b50565b5f8135905061433c81614318565b92915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61437c82613dc4565b810181811067ffffffffffffffff8211171561439b5761439a614346565b5b80604052505050565b5f6143ad613cbe565b90506143b98282614373565b919050565b5f67ffffffffffffffff8211156143d8576143d7614346565b5b602082029050602081019050919050565b5f80fd5b5f6143ff6143fa846143be565b6143a4565b90508083825260208201905060208402830185811115614422576144216143e9565b5b835b8181101561444b57806144378882613ea5565b845260208401935050602081019050614424565b5050509392505050565b5f82601f83011261446957614468614342565b5b81356144798482602086016143ed565b91505092915050565b5f805f805f8060c0878903121561449c5761449b613cc7565b5b5f6144a989828a01613e72565b96505060206144ba89828a01613e72565b95505060406144cb89828a01613ea5565b94505060606144dc89828a0161432e565b935050608087013567ffffffffffffffff8111156144fd576144fc613ccb565b5b61450989828a01614455565b92505060a087013567ffffffffffffffff81111561452a57614529613ccb565b5b61453689828a01614455565b9150509295509295509295565b61454c81613d4f565b8114614556575f80fd5b50565b5f8135905061456781614543565b92915050565b5f6020828403121561458257614581613cc7565b5b5f61458f84828501614559565b91505092915050565b5f80604083850312156145ae576145ad613cc7565b5b5f6145bb85828601613e72565b92505060206145cc85828601613e72565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061461a57607f821691505b60208210810361462d5761462c6145d6565b5b50919050565b7f5969646f6379546f6b656e203a206d696e74206973206e6f7420737570706f725f8201527f74656420666f72207468697320544f4b454e2121000000000000000000000000602082015250565b5f61468d603483613d8c565b915061469882614633565b604082019050919050565b5f6020820190508181035f8301526146ba81614681565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61472582613e86565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614757576147566146ee565b5b600182019050919050565b7f5969646f6379546f6b656e203a2043616e6e6f74207472616e736665722066725f8201527f6f6d206d6f7265207468616e207472616e7366657261626c6520616d6f756e74602082015250565b5f6147bc604083613d8c565b91506147c782614762565b604082019050919050565b5f6020820190508181035f8301526147e9816147b0565b9050919050565b7f5969646f6379546f6b656e203a206275726e206973206e6f7420737570706f725f8201527f74656420666f72207468697320544f4b454e2121000000000000000000000000602082015250565b5f61484a603483613d8c565b9150614855826147f0565b604082019050919050565b5f6020820190508181035f8301526148778161483e565b9050919050565b7f5969646f6379546f6b656e203a2072657175657374496420646f6573206e6f745f8201527f2065786973740000000000000000000000000000000000000000000000000000602082015250565b5f6148d8602683613d8c565b91506148e38261487e565b604082019050919050565b5f6020820190508181035f830152614905816148cc565b9050919050565b7f5969646f6379546f6b656e203a205265737472696374656420746f2061646d695f8201527f6e732e0000000000000000000000000000000000000000000000000000000000602082015250565b5f614966602383613d8c565b91506149718261490c565b604082019050919050565b5f6020820190508181035f8301526149938161495a565b9050919050565b7f5969646f6379546f6b656e203a2043616e6e6f74206164642061646d696e20725f8201527f6f6c6520666f72207a65726f2061646472657373000000000000000000000000602082015250565b5f6149f4603483613d8c565b91506149ff8261499a565b604082019050919050565b5f6020820190508181035f830152614a21816149e8565b9050919050565b5f614a3282613e86565b9150614a3d83613e86565b9250828203905081811115614a5557614a546146ee565b5b92915050565b7f5969646f6379546f6b656e203a2050726576696f75732041646d696e526f6c655f8201527f20526571756573742069732070656e64696e6700000000000000000000000000602082015250565b5f614ab5603383613d8c565b9150614ac082614a5b565b604082019050919050565b5f6020820190508181035f830152614ae281614aa9565b9050919050565b5f614af382613e86565b9150614afe83613e86565b9250828201905080821115614b1657614b156146ee565b5b92915050565b5f819050919050565b5f819050919050565b5f614b48614b43614b3e84614b1c565b614b25565b613e86565b9050919050565b614b5881614b2e565b82525050565b5f604082019050614b715f830185614b4f565b614b7e6020830184613fce565b9392505050565b7f5969646f6379546f6b656e203a20736574526577617264506f6f6c206d7573745f8201527f2063616c6c6564206f6e636520617420746865206465706c6f792074696d6500602082015250565b5f614bdf603f83613d8c565b9150614bea82614b85565b604082019050919050565b5f6020820190508181035f830152614c0c81614bd3565b9050919050565b7f5969646f6379546f6b656e203a20526577617264506f6f6c20616464726573735f8201527f2069732072657175697265640000000000000000000000000000000000000000602082015250565b5f614c6d602c83613d8c565b9150614c7882614c13565b604082019050919050565b5f6020820190508181035f830152614c9a81614c61565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffd5b7f5969646f6379546f6b656e203a204c6f636b75702064617465206c69737420615f8201527f6e6420616d6f756e74206c697374206d757374206265207468652073616d652060208201527f6c656e6774682100000000000000000000000000000000000000000000000000604082015250565b5f614d4e604783613d8c565b9150614d5982614cce565b606082019050919050565b5f6020820190508181035f830152614d7b81614d42565b9050919050565b7f5969646f6379546f6b656e203a204c6f636b75702076657374696e6720746f745f8201527f616c20616d6f756e74206d757374206265206c657373206f7220657175616c2060208201527f746f20746865206c6f636b757020616d6f756e74210000000000000000000000604082015250565b5f614e02605583613d8c565b9150614e0d82614d82565b606082019050919050565b5f6020820190508181035f830152614e2f81614df6565b9050919050565b7f5969646f6379546f6b656e203a205468657265206973206e6f206578637574615f8201527f626c652041646d696e526f6c6552657175657374000000000000000000000000602082015250565b5f614e90603483613d8c565b9150614e9b82614e36565b604082019050919050565b5f6020820190508181035f830152614ebd81614e84565b9050919050565b7f5969646f6379546f6b656e203a204e6f2041646d696e526f6c652052657175655f8201527f7374206973207265717565737465640000000000000000000000000000000000602082015250565b5f614f1e602f83613d8c565b9150614f2982614ec4565b604082019050919050565b5f6020820190508181035f830152614f4b81614f12565b9050919050565b7f5969646f6379546f6b656e203a20457865637574652052657175657374206d755f8201527f737420626520746865206f7468657220616d64696e526f6c6572000000000000602082015250565b5f614fac603a83613d8c565b9150614fb782614f52565b604082019050919050565b5f6020820190508181035f830152614fd981614fa0565b9050919050565b5f604082019050614ff35f830185613fce565b6150006020830184613fce565b9392505050565b7f5969646f6379546f6b656e203a2043616e6e6f74207472616e736665722061645f8201527f6d696e20726f6c6520746f207a65726f20616464726573730000000000000000602082015250565b5f615061603883613d8c565b915061506c82615007565b604082019050919050565b5f6020820190508181035f83015261508e81615055565b9050919050565b7f5969646f6379546f6b656e203a2043616e6e6f74207472616e736665722061645f8201527f6d696e20726f6c6520746f207468652073616d65206164647265737300000000602082015250565b5f6150ef603c83613d8c565b91506150fa82615095565b604082019050919050565b5f6020820190508181035f83015261511c816150e3565b9050919050565b5f819050919050565b5f61514661514161513c84615123565b614b25565b613e86565b9050919050565b6151568161512c565b82525050565b5f60408201905061516f5f83018561514d565b61517c6020830184613fce565b9392505050565b7f5969646f6379546f6b656e203a2043616e6e6f74207472616e73666572206d6f5f8201527f7265207468616e207472616e7366657261626c6520616d6f756e740000000000602082015250565b5f6151dd603b83613d8c565b91506151e882615183565b604082019050919050565b5f6020820190508181035f83015261520a816151d1565b9050919050565b5f6040820190506152245f830185614194565b6152316020830184613fce565b9392505050565b7f5969646f6379546f6b656e203a2043616e6e6f74206164642061646d696e20725f8201527f6f6c6520666f72207468652073616d6520616464726573730000000000000000602082015250565b5f615292603883613d8c565b915061529d82615238565b604082019050919050565b5f6020820190508181035f8301526152bf81615286565b9050919050565b5f819050919050565b5f6152e96152e46152df846152c6565b614b25565b613e86565b9050919050565b6152f9816152cf565b82525050565b5f6040820190506153125f8301856152f0565b61531f6020830184613fce565b9392505050565b5f6020820190506153395f830184614194565b92915050565b5f8151905061534d81613e8f565b92915050565b5f6020828403121561536857615367613cc7565b5b5f6153758482850161533f565b91505092915050565b5f6060820190506153915f830186614194565b61539e6020830185613fce565b6153ab6040830184613fce565b949350505050565b5f6040820190506153c65f830185614194565b6153d360208301846140a4565b939250505056fea264697066735822122055dd98f62b710ed3f7683d04260e292273c931c36f91d5efea235c1fe14fd59264736f6c63430008140033
Verified Source Code Partial Match
Compiler: v0.8.20+commit.a1b79de6
EVM: shanghai
Optimization: No
YidocyToken.sol 1351 lines
// File: @openzeppelin/contracts/token/ERC20/IERC20.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @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 value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` 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 value) external returns (bool);
}
// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*/
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);
}
// File: @openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
// File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard ERC20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
// File: @openzeppelin/contracts/token/ERC20/ERC20.sol
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
/**
* @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}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* 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.
*/
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
mapping(address account => uint256) private _balances;
mapping(address account => mapping(address spender => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* 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 returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual 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 default value returned by this function, unless
* it's 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 returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual 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 `value`.
*/
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `value` 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 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
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 `value`.
* - the caller must have allowance for ``from``'s tokens of at least
* `value`.
*/
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
/**
* @dev Moves a `value` 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.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
/**
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
* this function.
*
* Emits a {Transfer} event.
*/
function _update(address from, address to, uint256 value) internal virtual {
if (from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
_totalSupply += value;
} else {
uint256 fromBalance = _balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
_balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
_totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
_balances[to] += value;
}
}
emit Transfer(from, to, value);
}
/**
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
* Relies on the `_update` mechanism
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
* Relies on the `_update` mechanism.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead
*/
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
/**
* @dev Sets `value` 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.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
/**
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
*
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
* `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
* `Approval` event during `transferFrom` operations.
*
* Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
* true using the following override:
* ```
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
* super._approve(owner, spender, value, true);
* }
* ```
*
* Requirements are the same as {_approve}.
*/
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
_allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `value`.
*
* Does not update the allowance value in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Does not emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}
// File: @openzeppelin/contracts/access/IAccessControl.sol
// OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol)
pragma solidity ^0.8.20;
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}
// File: @openzeppelin/contracts/utils/introspection/IERC165.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
// File: @openzeppelin/contracts/utils/introspection/ERC165.sol
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
// File: @openzeppelin/contracts/access/AccessControl.sol
// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
mapping(bytes32 role => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
return _roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
if (!hasRole(role, account)) {
_roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
if (hasRole(role, account)) {
_roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}
// File: IRewardPool.sol
pragma solidity ^0.8.0;
interface IRewardPool {
function notifyReward(uint256 amount) external;
function getUserStakingBalance(address account) external view returns(uint256);
function deposit(address staker, uint256 amount) external;
}
// File: YidocyToken.sol
pragma solidity ^0.8.0;
contract YidocyToken is ERC20, AccessControl {
uint256 internal immutable _supplyCap;
IRewardPool internal _rewardPool;
struct VestingSchedule {
uint256 validFromDate;
uint256 amount;
}
struct LockupInfo {
uint256 lockupAmount;
uint256 code; // 1: Team, 2: Advisor, 3: Private Sale
address rewardPoolAddress;
VestingSchedule[] vestingSchedules;
}
address[] internal _userLockupAddresses;
mapping(address => LockupInfo) internal _userLockups;
address[] internal _adminRoleMembers;
struct AdminRoleRequest {
address newAdmin;
address revokeAdmin;
uint256 action; // 1: add, 2: revoke, 3: transfer
uint256 status; // 0: requested, 1: executed, 2: rejected
address requestedAdmin;
address approvedAdmin;
address rejectedAdmin;
}
mapping(uint256 => AdminRoleRequest) internal _adminRoleRequests;
uint256 internal _adminRoleRequestCount;
event AdminRoleTransferred(address indexed currentAdmin, address indexed newAdmin, uint256 requestId);
event AdminRoleAdded(address indexed performedAdmin, address indexed newAdmin, uint256 requestId);
event AdminRoleRevoked(address indexed performedAdmin, address indexed revokedAdmin, uint256 requestId);
event AdminRoleRequested(address indexed requesteAdmin, uint256 action, uint256 requestId);
event AdminRoleRejected(address indexed rejectedAdmin, uint256 action, uint256 requestId);
modifier onlyAdmin() {
require(_isAdmin(msg.sender), "YidocyToken : Restricted to admins.");
_;
}
constructor(address[] memory multiAdminRoles, uint256 supplyCap) ERC20("Yidocy", "YIDO") {
require(multiAdminRoles.length > 1, "YidocyToken : Number of multiAdminRoles must be over 1");
for (uint256 i = 0; i < multiAdminRoles.length; i++) {
require(multiAdminRoles[i] != address(0), "YidocyToken : multiAdminRole address could not be zero");
require(multiAdminRoles[i] != msg.sender, "YidocyToken : Except contructor, number of multiAdminRoles must be over 1");
}
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_adminRoleMembers.push(msg.sender);
for (uint256 i = 0; i < multiAdminRoles.length; i++) {
_adminRoleMembers.push(multiAdminRoles[i]);
_grantRole(DEFAULT_ADMIN_ROLE, multiAdminRoles[i]);
}
_supplyCap = supplyCap;
_mint(msg.sender, _supplyCap);
}
function decimals() public view virtual override returns (uint8) {
return 8;
}
function getLockupUsers() external view returns(address[] memory) {
return _userLockupAddresses;
}
function getUserLockup(address account) external view returns(
uint256 lockupAmount,
uint256 code,
uint256[] memory vestingValidFromDateList,
uint256[] memory vestingAmountList
) {
lockupAmount = 0;
LockupInfo memory userLockup = _userLockups[account];
if (userLockup.lockupAmount > 0) {
lockupAmount = userLockup.lockupAmount;
code = userLockup.code;
vestingValidFromDateList = new uint256[](userLockup.vestingSchedules.length);
vestingAmountList = new uint256[](userLockup.vestingSchedules.length);
for (uint256 i = 0; i < userLockup.vestingSchedules.length; i++) {
vestingValidFromDateList[i] = userLockup.vestingSchedules[i].validFromDate;
vestingAmountList[i] = userLockup.vestingSchedules[i].amount;
}
}
}
function transferableAmount(address sender, address recipient) internal view returns (uint256){
uint256 senderBalanceOf = balanceOf(sender);
LockupInfo memory userLockup = _userLockups[sender];
if (userLockup.lockupAmount == 0 || userLockup.rewardPoolAddress == recipient) {
return senderBalanceOf;
}
uint256 senderStakingBalanceOf = IRewardPool(userLockup.rewardPoolAddress).getUserStakingBalance(sender);
uint256 amount = senderBalanceOf + senderStakingBalanceOf;
uint256 nowTimestamp = uint256(block.timestamp);
uint256 vestingScheduleLength = userLockup.vestingSchedules.length;
for (uint256 i = 0; i < vestingScheduleLength; i++) {
if (userLockup.vestingSchedules[i].validFromDate > nowTimestamp) {
if (amount < userLockup.vestingSchedules[i].amount) {
return 0;
}
amount -= userLockup.vestingSchedules[i].amount;
}
}
if (amount >= senderBalanceOf) {
return senderBalanceOf;
}
return amount;
}
function stakeToken(uint256 amount) external {
transfer(address(_rewardPool), amount);
_rewardPool.deposit(msg.sender, amount);
}
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
require(transferableAmount(_msgSender(), recipient) >= amount, "YidocyToken : Cannot transfer more than transferable amount");
return super.transfer(recipient, amount);
}
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
require(transferableAmount(sender, recipient) >= amount, "YidocyToken : Cannot transfer from more than transferable amount");
return super.transferFrom(sender, recipient, amount);
}
function mint() external pure {
revert("YidocyToken : mint is not supported for this TOKEN!!");
}
function setRewardPool(address rewardPool) external onlyAdmin {
require(address(_rewardPool) == address(0), "YidocyToken : setRewardPool must called once at the deploy time");
require(rewardPool != address(0), "YidocyToken : RewardPool address is required");
_rewardPool = IRewardPool(rewardPool);
}
function burn() external pure {
revert("YidocyToken : burn is not supported for this TOKEN!!");
}
function setUserLockup(
address rewardPoolAddress,
address account,
uint256 lockupAmount,
uint8 code, // 1: Team, 2: Advisor, 3: Private Sale
uint256[] memory vestingValidFromDateList,
uint256[] memory vestingAmountList
) external onlyAdmin {
if (lockupAmount == 0) {
delete _userLockups[account];
uint256 addressLength = _userLockupAddresses.length;
for (uint256 i = 0; i < addressLength; i++) {
if (_userLockupAddresses[i] == account) {
delete _userLockupAddresses[i];
_userLockupAddresses[i] = _userLockupAddresses[addressLength-1];
_userLockupAddresses.pop();
break;
}
}
return;
}
require(vestingValidFromDateList.length == vestingAmountList.length, "YidocyToken : Lockup date list and amount list must be the same length!");
uint256 vestingTotalAmount = 0;
for (uint256 i = 0; i < vestingValidFromDateList.length; i++) {
vestingTotalAmount += vestingAmountList[i];
}
require(vestingTotalAmount <= lockupAmount, "YidocyToken : Lockup vesting total amount must be less or equal to the lockup amount!");
_userLockups[account].lockupAmount = lockupAmount;
_userLockups[account].code = code;
_userLockups[account].rewardPoolAddress = rewardPoolAddress;
delete _userLockups[account].vestingSchedules;
for (uint256 i = 0; i < vestingValidFromDateList.length; i++) {
_userLockups[account].vestingSchedules.push(VestingSchedule(vestingValidFromDateList[i], vestingAmountList[i]));
}
bool addressFound = false;
uint256 userLockupAddressLength = _userLockupAddresses.length;
for (uint256 i = 0; i < userLockupAddressLength; i++) {
if (_userLockupAddresses[i] == account) {
addressFound = true;
break;
}
}
if (!addressFound) {
_userLockupAddresses.push(account);
}
}
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
}
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
}
function renounceRole(bytes32 role, address callerConfirmation) public virtual override {
}
function _isAdmin(address account) internal view returns (bool) {
return hasRole(DEFAULT_ADMIN_ROLE, account);
}
function isAdmin(address account) external view returns (bool) {
return hasRole(DEFAULT_ADMIN_ROLE, account);
}
function _adminRoleMembersCount() internal view returns (uint256) {
uint256 count = 0;
for (uint256 i = 0; i < _adminRoleMembers.length; i++) {
if (_adminRoleMembers[i] != address(0)) {
count++;
}
}
return count;
}
function adminRoleMembersCount() external view returns (uint256) {
return _adminRoleMembersCount();
}
function getAdminRoleMembers() external view returns (address[] memory adminRoleMembers) {
adminRoleMembers = new address[](_adminRoleMembersCount());
uint256 index = 0;
for (uint256 i = 0; i < _adminRoleMembers.length; i++) {
if (_adminRoleMembers[i] != address(0)) {
adminRoleMembers[index++] = _adminRoleMembers[i];
}
}
}
function getAdminRoleRequestCount() external view returns(uint256) {
return _adminRoleRequestCount;
}
function getAdminRoleRequest(uint256 requestId) external view returns (
address newAdmin,
address revokeAdmin,
uint256 action,
uint256 status,
address requestedAdmin,
address approvedAdmin,
address rejectedAdmin
) {
require(requestId < _adminRoleRequestCount, "YidocyToken : requestId does not exist");
newAdmin = _adminRoleRequests[requestId].newAdmin;
revokeAdmin = _adminRoleRequests[requestId].revokeAdmin;
action = _adminRoleRequests[requestId].action;
status = _adminRoleRequests[requestId].status;
requestedAdmin = _adminRoleRequests[requestId].requestedAdmin;
approvedAdmin = _adminRoleRequests[requestId].approvedAdmin;
rejectedAdmin = _adminRoleRequests[requestId].newAdmin;
}
function requestTransferAdminRole(address newAdmin) external onlyAdmin returns(uint256) {
require(newAdmin != address(0), "YidocyToken : Cannot transfer admin role to zero address");
require(newAdmin != msg.sender, "YidocyToken : Cannot transfer admin role to the same address");
require(_adminRoleRequestCount == 0 || _adminRoleRequests[_adminRoleRequestCount-1].status > 0, "YidocyToken : Previous AdminRole Request is pending");
uint256 requestId = _adminRoleRequestCount;
_adminRoleRequestCount += 1;
_adminRoleRequests[requestId] = AdminRoleRequest({
newAdmin: newAdmin,
revokeAdmin: msg.sender,
action: 3,
status: 0,
requestedAdmin: msg.sender,
approvedAdmin: address(0),
rejectedAdmin: address(0)
});
emit AdminRoleRequested(msg.sender, 3, requestId);
return requestId;
}
function requestAddAdminRole(address newAdmin) external onlyAdmin returns(uint256) {
require(newAdmin != address(0), "YidocyToken : Cannot add admin role for zero address");
require(newAdmin != msg.sender, "YidocyToken : Cannot add admin role for the same address");
require(_adminRoleRequestCount == 0 || _adminRoleRequests[_adminRoleRequestCount-1].status > 0, "YidocyToken : Previous AdminRole Request is pending");
uint256 requestId = _adminRoleRequestCount;
_adminRoleRequestCount += 1;
_adminRoleRequests[requestId] = AdminRoleRequest({
newAdmin: newAdmin,
revokeAdmin: address(0),
action: 1,
status: 0,
requestedAdmin: msg.sender,
approvedAdmin: address(0),
rejectedAdmin: address(0)
});
emit AdminRoleRequested(msg.sender, 1, requestId);
return requestId;
}
function requestRevokeAdminRole(address revokeAdmin) external onlyAdmin returns(uint256) {
require(revokeAdmin != address(0), "YidocyToken : Cannot add admin role for zero address");
require(_adminRoleRequestCount == 0 || _adminRoleRequests[_adminRoleRequestCount-1].status > 0, "YidocyToken : Previous AdminRole Request is pending");
uint256 requestId = _adminRoleRequestCount;
_adminRoleRequestCount += 1;
_adminRoleRequests[requestId] = AdminRoleRequest({
newAdmin: address(0),
revokeAdmin: revokeAdmin,
action: 2,
status: 0,
requestedAdmin: msg.sender,
approvedAdmin: address(0),
rejectedAdmin: address(0)
});
emit AdminRoleRequested(msg.sender, 2, requestId);
return requestId;
}
function executeRequestAdminRole(bool approval) external onlyAdmin returns(uint256) {
require(_adminRoleRequestCount > 0, "YidocyToken : There is no excutable AdminRoleRequest");
uint256 requestId = _adminRoleRequestCount-1;
require(_adminRoleRequestCount > 0 && _adminRoleRequests[requestId].status == 0, "YidocyToken : No AdminRole Request is requested");
require(msg.sender != _adminRoleRequests[requestId].requestedAdmin, "YidocyToken : Execute Request must be the other amdinRoler");
if (approval) {
_adminRoleRequests[requestId].status = 1;
_adminRoleRequests[requestId].approvedAdmin = msg.sender;
_adminRoleRequests[requestId].rejectedAdmin = address(0);
if (_adminRoleRequests[requestId].action == 1) { // add new AdminRole
_grantRole(DEFAULT_ADMIN_ROLE, _adminRoleRequests[requestId].newAdmin);
_adminRoleMembers.push(_adminRoleRequests[requestId].newAdmin);
emit AdminRoleAdded(...
// [truncated — 51747 bytes total]
Read Contract
DEFAULT_ADMIN_ROLE 0xa217fddf → bytes32
adminRoleMembersCount 0x4fa4544f → uint256
allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
burn 0x44df8e70
decimals 0x313ce567 → uint8
getAdminRoleMembers 0x1394de35 → address[]
getAdminRoleRequest 0x4cfc302a → address, address, uint256, uint256, address, address, address
getAdminRoleRequestCount 0xa136e2e9 → uint256
getLockupUsers 0xcf9dfe67 → address[]
getRoleAdmin 0x248a9ca3 → bytes32
getUserLockup 0x7d2597bc → uint256, uint256, uint256[], uint256[]
hasRole 0x91d14854 → bool
isAdmin 0x24d7806c → bool
mint 0x1249c58b
name 0x06fdde03 → string
supportsInterface 0x01ffc9a7 → bool
symbol 0x95d89b41 → string
totalSupply 0x18160ddd → uint256
Write Contract 13 functions
These functions modify contract state and require a wallet transaction to execute.
approve 0x095ea7b3
address spender
uint256 value
returns: bool
executeRequestAdminRole 0x94d74d8f
bool approval
returns: uint256
grantRole 0x2f2ff15d
bytes32 role
address account
renounceRole 0x36568abe
bytes32 role
address callerConfirmation
requestAddAdminRole 0xfb66da2c
address newAdmin
returns: uint256
requestRevokeAdminRole 0x6548ec3c
address revokeAdmin
returns: uint256
requestTransferAdminRole 0x97a909c5
address newAdmin
returns: uint256
revokeRole 0xd547741f
bytes32 role
address account
setRewardPool 0x78238c37
address rewardPool
setUserLockup 0x94c0b71b
address rewardPoolAddress
address account
uint256 lockupAmount
uint8 code
uint256[] vestingValidFromDateList
uint256[] vestingAmountList
stakeToken 0xcda6b847
uint256 amount
transfer 0xa9059cbb
address recipient
uint256 amount
returns: bool
transferFrom 0x23b872dd
address sender
address recipient
uint256 amount
returns: bool
Recent Transactions
No transactions found for this address