Address Contract Partially Verified
Address
0x80cb7272e8dAa79124DA78C09e0ab640136c8ba3
Balance
0 ETH
Nonce
1
Code Size
20479 bytes
Creator
0x6C3C3224...dcA2 at tx 0x8ce62f06...416d21
Indexed Transactions
0
Contract Bytecode
20479 bytes
0x60806040526004361061036a575f3560e01c80637ec4a659116101c5578063b071401b116100f6578063d8a7de1e11610094578063e985e9c51161006e578063e985e9c514610bfa578063efbd73f414610c36578063f2fde38b14610c5e578063f4a0a52814610c865761036a565b8063d8a7de1e14610b7e578063e0a8085314610ba8578063e5c5f1d514610bd05761036a565b8063b8c489e1116100d0578063b8c489e114610ac8578063c39cbef114610af0578063c78ad77f14610b18578063c87b56dd14610b425761036a565b8063b071401b14610a5a578063b42f0fb814610a82578063b88d4fde14610aac5761036a565b806395d89b4111610163578063a0712d681161013d578063a0712d68146109c2578063a22cb465146109de578063a45ba8e714610a06578063a675ca2f14610a305761036a565b806395d89b411461093257806399b1755b1461095c5780639ffdb65a146109865761036a565b80638c0f66db1161019f5780638c0f66db1461087a5780638da5cb5b146108a25780639416b423146108cc57806394354fd0146109085761036a565b80637ec4a6591461080e5780637ec7e7a41461083657806384a1b902146108525761036a565b8063466429211161029f57806362b99ad41161023d5780636bf8a5f6116102175780636bf8a5f6146107565780636d5224181461078057806370a08231146107bc578063715018a6146107f85761036a565b806362b99ad4146106c85780636352211e146106f257806365657c411461072e5761036a565b806354c6191d1161027957806354c6191d146106245780635503a0e81461064e57806355c8d840146106785780635da4a1d3146106a05761036a565b806346642921146105aa5780634fdd43cb146105d257806351830227146105fa5761036a565b806318160ddd1161030c5780633ccfd60b116102e65780633ccfd60b146105285780633db82fb51461053e5780633ebee8f51461056657806342842e0e1461058e5761036a565b806318160ddd146104ba57806323b872dd146104e457806332744e3a146105005761036a565b8063095ea7b311610348578063095ea7b31461041057806313faede61461042c57806315b56d101461045657806316ba10e0146104925761036a565b806301ffc9a71461036e57806306fdde03146103aa578063081812fc146103d4575b5f80fd5b348015610379575f80fd5b50610394600480360381019061038f9190613b94565b610cae565b6040516103a19190613bd9565b60405180910390f35b3480156103b5575f80fd5b506103be610d3f565b6040516103cb9190613c7c565b60405180910390f35b3480156103df575f80fd5b506103fa60048036038101906103f59190613ccf565b610dcf565b6040516104079190613d39565b60405180910390f35b61042a60048036038101906104259190613d7c565b610e49565b005b348015610437575f80fd5b50610440610f88565b60405161044d9190613dc9565b60405180910390f35b348015610461575f80fd5b5061047c60048036038101906104779190613f0e565b610f8e565b6040516104899190613bd9565b60405180910390f35b34801561049d575f80fd5b506104b860048036038101906104b39190613f0e565b610fc9565b005b3480156104c5575f80fd5b506104ce610fe4565b6040516104db9190613dc9565b60405180910390f35b6104fe60048036038101906104f99190613f55565b610ff9565b005b34801561050b575f80fd5b5061052660048036038101906105219190613fa5565b611307565b005b348015610533575f80fd5b5061053c611352565b005b348015610549575f80fd5b50610564600480360381019061055f9190613ccf565b6114ab565b005b348015610571575f80fd5b5061058c60048036038101906105879190613fa5565b6114bd565b005b6105a860048036038101906105a39190613f55565b611508565b005b3480156105b5575f80fd5b506105d060048036038101906105cb9190613fa5565b611527565b005b3480156105dd575f80fd5b506105f860048036038101906105f39190613f0e565b611572565b005b348015610605575f80fd5b5061060e61158d565b60405161061b9190613bd9565b60405180910390f35b34801561062f575f80fd5b5061063861159f565b6040516106459190613dc9565b60405180910390f35b348015610659575f80fd5b506106626115a5565b60405161066f9190613c7c565b60405180910390f35b348015610683575f80fd5b5061069e60048036038101906106999190613fa5565b611631565b005b3480156106ab575f80fd5b506106c660048036038101906106c19190613ccf565b61167c565b005b3480156106d3575f80fd5b506106dc61168e565b6040516106e99190613c7c565b60405180910390f35b3480156106fd575f80fd5b5061071860048036038101906107139190613ccf565b61171a565b6040516107259190613d39565b60405180910390f35b348015610739575f80fd5b50610754600480360381019061074f9190613fd0565b61172b565b005b348015610761575f80fd5b5061076a611a6f565b6040516107779190613d39565b60405180910390f35b34801561078b575f80fd5b506107a660048036038101906107a19190613ccf565b611a94565b6040516107b39190613c7c565b60405180910390f35b3480156107c7575f80fd5b506107e260048036038101906107dd9190613fa5565b611b35565b6040516107ef9190613dc9565b60405180910390f35b348015610803575f80fd5b5061080c611bea565b005b348015610819575f80fd5b50610834600480360381019061082f9190613f0e565b611bfd565b005b610850600480360381019061084b9190613fd0565b611c9f565b005b34801561085d575f80fd5b5061087860048036038101906108739190613ccf565b612020565b005b348015610885575f80fd5b506108a0600480360381019061089b9190613fa5565b612032565b005b3480156108ad575f80fd5b506108b661207d565b6040516108c39190613d39565b60405180910390f35b3480156108d7575f80fd5b506108f260048036038101906108ed9190613f0e565b6120a5565b6040516108ff9190613c7c565b60405180910390f35b348015610913575f80fd5b5061091c612252565b6040516109299190613dc9565b60405180910390f35b34801561093d575f80fd5b50610946612258565b6040516109539190613c7c565b60405180910390f35b348015610967575f80fd5b506109706122e8565b60405161097d9190613dc9565b60405180910390f35b348015610991575f80fd5b506109ac60048036038101906109a79190613f0e565b6122ee565b6040516109b99190613bd9565b60405180910390f35b6109dc60048036038101906109d79190613ccf565b61260c565b005b3480156109e9575f80fd5b50610a0460048036038101906109ff9190614054565b612760565b005b348015610a11575f80fd5b50610a1a612866565b604051610a279190613c7c565b60405180910390f35b348015610a3b575f80fd5b50610a446128f2565b604051610a519190613dc9565b60405180910390f35b348015610a65575f80fd5b50610a806004803603810190610a7b9190613ccf565b6128f8565b005b348015610a8d575f80fd5b50610a9661290a565b604051610aa391906140ed565b60405180910390f35b610ac66004803603810190610ac191906141a4565b61292f565b005b348015610ad3575f80fd5b50610aee6004803603810190610ae99190613ccf565b6129a1565b005b348015610afb575f80fd5b50610b166004803603810190610b119190613fd0565b6129b3565b005b348015610b23575f80fd5b50610b2c612db1565b604051610b399190613dc9565b60405180910390f35b348015610b4d575f80fd5b50610b686004803603810190610b639190613ccf565b612db7565b604051610b759190613c7c565b60405180910390f35b348015610b89575f80fd5b50610b92612f08565b604051610b9f9190613dc9565b60405180910390f35b348015610bb3575f80fd5b50610bce6004803603810190610bc99190614224565b612f0e565b005b348015610bdb575f80fd5b50610be4612f32565b604051610bf19190613d39565b60405180910390f35b348015610c05575f80fd5b50610c206004803603810190610c1b919061424f565b612f57565b604051610c2d9190613bd9565b60405180910390f35b348015610c41575f80fd5b50610c5c6004803603810190610c57919061428d565b612fe5565b005b348015610c69575f80fd5b50610c846004803603810190610c7f9190613fa5565b613054565b005b348015610c91575f80fd5b50610cac6004803603810190610ca79190613ccf565b6130d8565b005b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610d0857506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610d385750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b606060028054610d4e906142f8565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7a906142f8565b8015610dc55780601f10610d9c57610100808354040283529160200191610dc5565b820191905f5260205f20905b815481529060010190602001808311610da857829003601f168201915b5050505050905090565b5f610dd9826130ea565b610e0f576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f610e538261171a565b90508073ffffffffffffffffffffffffffffffffffffffff16610e74613144565b73ffffffffffffffffffffffffffffffffffffffff1614610ed757610ea081610e9b613144565b612f57565b610ed6576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b8260065f8481526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600f5481565b5f601b610f9a836120a5565b604051610fa79190614362565b90815260200160405180910390205f9054906101000a900460ff169050919050565b610fd161314b565b8060179081610fe0919061450c565b5050565b5f610fed6131d2565b6001545f540303905090565b5f611003826131da565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461106a576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f806110758461329d565b9150915061108b8187611086613144565b6132c0565b6110d7576110a08661109b613144565b612f57565b6110d6576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361113c576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111498686866001613303565b8015611153575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f81546001019190508190555061121b856111f7888887613309565b7c020000000000000000000000000000000000000000000000000000000017613330565b60045f8681526020019081526020015f20819055505f7c0200000000000000000000000000000000000000000000000000000000841603611297575f6001850190505f60045f8381526020019081526020015f205403611295575f548114611294578360045f8381526020019081526020015f20819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46112ff868686600161335a565b505050505050565b61130f61314b565b8060155f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61135a61314b565b611362613360565b5f60115f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166064601054476113ab9190614608565b6113b59190614676565b6040516113c1906146d3565b5f6040518083038185875af1925050503d805f81146113fb576040519150601f19603f3d011682016040523d82523d5f602084013e611400565b606091505b505090508061140d575f80fd5b5f60125f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1647604051611453906146d3565b5f6040518083038185875af1925050503d805f811461148d576040519150601f19603f3d011682016040523d82523d5f602084013e611492565b606091505b505090508061149f575f80fd5b50506114a96133af565b565b6114b361314b565b80600a8190555050565b6114c561314b565b8060115f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61152283838360405180602001604052805f81525061292f565b505050565b61152f61314b565b8060135f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61157a61314b565b8060189081611589919061450c565b5050565b60195f9054906101000a900460ff1681565b600b5481565b601780546115b2906142f8565b80601f01602080910402602001604051908101604052809291908181526020018280546115de906142f8565b80156116295780601f1061160057610100808354040283529160200191611629565b820191905f5260205f20905b81548152906001019060200180831161160c57829003601f168201915b505050505081565b61163961314b565b8060125f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61168461314b565b8060108190555050565b6016805461169b906142f8565b80601f01602080910402602001604051908101604052809291908181526020018280546116c7906142f8565b80156117125780601f106116e957610100808354040283529160200191611712565b820191905f5260205f20905b8154815290600101906020018083116116f557829003601f168201915b505050505081565b5f611724826131da565b9050919050565b81815f6117378361171a565b90508073ffffffffffffffffffffffffffffffffffffffff166117586133b9565b73ffffffffffffffffffffffffffffffffffffffff16146117ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117a590614731565b60405180910390fd5b600115156117bb836122ee565b1515146117fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f490614799565b60405180910390fd5b6002601a5f8581526020019081526020015f2060405161181d9190614849565b602060405180830381855afa158015611838573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061185b9190614892565b60028360405161186b91906148f7565b602060405180830381855afa158015611886573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906118a99190614892565b036118e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e09061497d565b60405180910390fd5b5f15156118f583610f8e565b151514611937576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192e906149e5565b60405180910390fd5b61193f61314b565b5f601a5f8781526020019081526020015f20805461195c906142f8565b90501115611a0657611a05601a5f8781526020019081526020015f208054611983906142f8565b80601f01602080910402602001604051908101604052809291908181526020018280546119af906142f8565b80156119fa5780601f106119d1576101008083540402835291602001916119fa565b820191905f5260205f20905b8154815290600101906020018083116119dd57829003601f168201915b50505050505f6133c0565b5b611a118460016133c0565b83601a5f8781526020019081526020015f209081611a2f919061450c565b50847f7e632a301794d8d4a81ea7e20f37d1947158d36e66403af04ba85dd194b66f1b85604051611a609190613c7c565b60405180910390a25050505050565b60135f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060601a5f8381526020019081526020015f208054611ab2906142f8565b80601f0160208091040260200160405190810160405280929190818152602001828054611ade906142f8565b8015611b295780601f10611b0057610100808354040283529160200191611b29565b820191905f5260205f20905b815481529060010190602001808311611b0c57829003601f168201915b50505050509050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611b9b576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b611bf261314b565b611bfb5f613401565b565b60135f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8390614a4d565b60405180910390fd5b8060169081611c9b919061450c565b5050565b81815f611cab8361171a565b90508073ffffffffffffffffffffffffffffffffffffffff16611ccc6133b9565b73ffffffffffffffffffffffffffffffffffffffff1614611d22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1990614731565b60405180910390fd5b60011515611d2f836122ee565b151514611d71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d6890614799565b60405180910390fd5b6002601a5f8581526020019081526020015f20604051611d919190614849565b602060405180830381855afa158015611dac573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611dcf9190614892565b600283604051611ddf91906148f7565b602060405180830381855afa158015611dfa573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190611e1d9190614892565b03611e5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e549061497d565b60405180910390fd5b5f1515611e6983610f8e565b151514611eab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ea2906149e5565b60405180910390fd5b600e54341015611ef0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ee790614ab5565b60405180910390fd5b5f601a5f8781526020019081526020015f208054611f0d906142f8565b90501115611fb757611fb6601a5f8781526020019081526020015f208054611f34906142f8565b80601f0160208091040260200160405190810160405280929190818152602001828054611f60906142f8565b8015611fab5780601f10611f8257610100808354040283529160200191611fab565b820191905f5260205f20905b815481529060010190602001808311611f8e57829003601f168201915b50505050505f6133c0565b5b611fc28460016133c0565b83601a5f8781526020019081526020015f209081611fe0919061450c565b50847f7e632a301794d8d4a81ea7e20f37d1947158d36e66403af04ba85dd194b66f1b856040516120119190613c7c565b60405180910390a25050505050565b61202861314b565b80600d8190555050565b61203a61314b565b8060145f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60605f8290505f815167ffffffffffffffff8111156120c7576120c6613dea565b5b6040519080825280601f01601f1916602001820160405280156120f95781602001600182028036833780820191505090505b5090505f5b825181101561224757604183828151811061211c5761211b614ad3565b5b602001015160f81c60f81b60f81c60ff161015801561215f5750605a83828151811061214b5761214a614ad3565b5b602001015160f81c60f81b60f81c60ff1611155b156121da57602083828151811061217957612178614ad3565b5b602001015160f81c60f81b60f81c6121919190614b0c565b60f81b8282815181106121a7576121a6614ad3565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535061223a565b8281815181106121ed576121ec614ad3565b5b602001015160f81c60f81b82828151811061220b5761220a614ad3565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505b80806001019150506120fe565b508092505050919050565b600c5481565b606060038054612267906142f8565b80601f0160208091040260200160405190810160405280929190818152602001828054612293906142f8565b80156122de5780601f106122b5576101008083540402835291602001916122de565b820191905f5260205f20905b8154815290600101906020018083116122c157829003601f168201915b5050505050905090565b600a5481565b5f80829050600181511015612306575f915050612607565b601981511115612319575f915050612607565b602060f81b815f8151811061233157612330614ad3565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361236c575f915050612607565b602060f81b81600183516123809190614b40565b8151811061239157612390614ad3565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036123cc575f915050612607565b5f815f815181106123e0576123df614ad3565b5b602001015160f81c60f81b90505f5b82518110156125ff575f83828151811061240c5761240b614ad3565b5b602001015160f81c60f81b9050602060f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480156124735750602060f81b837effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b15612484575f945050505050612607565b603060f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101580156124e05750603960f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191611155b1580156125465750604160f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101580156125445750605a60f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191611155b155b80156125ab5750606160f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916101580156125a95750607a60f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191611155b155b80156125dd5750602060f81b817effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614155b156125ee575f945050505050612607565b8092505080806001019150506123ef565b506001925050505b919050565b80600b5481612619610fe4565b6126239190614b73565b1115612664576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265b90614bf0565b60405180910390fd5b8180600f546126739190614608565b3410156126b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126ac90614ab5565b60405180910390fd5b600a544210156126fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f190614c58565b60405180910390fd5b5f8311801561270b5750600c548311155b61274a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161274190614cc0565b60405180910390fd5b61275b6127556133b9565b846134c4565b505050565b8060075f61276c613144565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612815613144565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161285a9190613bd9565b60405180910390a35050565b60188054612873906142f8565b80601f016020809104026020016040519081016040528092919081815260200182805461289f906142f8565b80156128ea5780601f106128c1576101008083540402835291602001916128ea565b820191905f5260205f20905b8154815290600101906020018083116128cd57829003601f168201915b505050505081565b600e5481565b61290061314b565b80600c8190555050565b60155f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61293a848484610ff9565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1461299b57612964848484846134e1565b61299a576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6129a961314b565b80600e8190555050565b81815f6129bf8361171a565b90508073ffffffffffffffffffffffffffffffffffffffff166129e06133b9565b73ffffffffffffffffffffffffffffffffffffffff1614612a36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a2d90614731565b60405180910390fd5b60011515612a43836122ee565b151514612a85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a7c90614799565b60405180910390fd5b6002601a5f8581526020019081526020015f20604051612aa59190614849565b602060405180830381855afa158015612ac0573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190612ae39190614892565b600283604051612af391906148f7565b602060405180830381855afa158015612b0e573d5f803e3d5ffd5b5050506040513d601f19601f82011682018060405250810190612b319190614892565b03612b71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b689061497d565b60405180910390fd5b5f1515612b7d83610f8e565b151514612bbf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bb6906149e5565b60405180910390fd5b60155f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3360145f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600d546040518463ffffffff1660e01b8152600401612c4093929190614cde565b6020604051808303815f875af1158015612c5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c809190614d27565b505f601a5f8781526020019081526020015f208054612c9e906142f8565b90501115612d4857612d47601a5f8781526020019081526020015f208054612cc5906142f8565b80601f0160208091040260200160405190810160405280929190818152602001828054612cf1906142f8565b8015612d3c5780601f10612d1357610100808354040283529160200191612d3c565b820191905f5260205f20905b815481529060010190602001808311612d1f57829003601f168201915b50505050505f6133c0565b5b612d538460016133c0565b83601a5f8781526020019081526020015f209081612d71919061450c565b50847f7e632a301794d8d4a81ea7e20f37d1947158d36e66403af04ba85dd194b66f1b85604051612da29190613c7c565b60405180910390a25050505050565b60105481565b6060612dc2826130ea565b612e01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612df890614dc2565b60405180910390fd5b5f151560195f9054906101000a900460ff16151503612eaa5760188054612e27906142f8565b80601f0160208091040260200160405190810160405280929190818152602001828054612e53906142f8565b8015612e9e5780601f10612e7557610100808354040283529160200191612e9e565b820191905f5260205f20905b815481529060010190602001808311612e8157829003601f168201915b50505050509050612f03565b5f612eb361362c565b90505f815111612ed15760405180602001604052805f815250612eff565b80612edb846136bc565b6017604051602001612eef93929190614e60565b6040516020818303038152906040525b9150505b919050565b600d5481565b612f1661314b565b8060195f6101000a81548160ff02191690831515021790555050565b60145f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b81600b5481612ff2610fe4565b612ffc9190614b73565b111561303d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161303490614bf0565b60405180910390fd5b61304561314b565b61304f82846134c4565b505050565b61305c61314b565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036130cc575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016130c39190613d39565b60405180910390fd5b6130d581613401565b50565b6130e061314b565b80600f8190555050565b5f816130f46131d2565b1115801561310257505f5482105b801561313d57505f7c010000000000000000000000000000000000000000000000000000000060045f8581526020019081526020015f205416145b9050919050565b5f33905090565b6131536133b9565b73ffffffffffffffffffffffffffffffffffffffff1661317161207d565b73ffffffffffffffffffffffffffffffffffffffff16146131d0576131946133b9565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016131c79190613d39565b60405180910390fd5b565b5f6001905090565b5f80829050806131e86131d2565b11613266575f54811015613265575f60045f8381526020019081526020015f205490505f7c0100000000000000000000000000000000000000000000000000000000821603613263575b5f81036132595760045f836001900393508381526020019081526020015f20549050613232565b8092505050613298565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e861331f868684613786565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6002600954036133a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161339c90614eda565b60405180910390fd5b6002600981905550565b6001600981905550565b5f33905090565b80601b6133cc846120a5565b6040516133d99190614362565b90815260200160405180910390205f6101000a81548160ff0219169083151502179055505050565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6134dd828260405180602001604052805f81525061378e565b5050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613506613144565b8786866040518563ffffffff1660e01b81526004016135289493929190614f40565b6020604051808303815f875af192505050801561356357506040513d601f19601f820116820180604052508101906135609190614f9e565b60015b6135d9573d805f8114613591576040519150601f19603f3d011682016040523d82523d5f602084013e613596565b606091505b505f8151036135d1576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606016805461363b906142f8565b80601f0160208091040260200160405190810160405280929190818152602001828054613667906142f8565b80156136b25780601f10613689576101008083540402835291602001916136b2565b820191905f5260205f20905b81548152906001019060200180831161369557829003601f168201915b5050505050905090565b60605f60016136ca84613825565b0190505f8167ffffffffffffffff8111156136e8576136e7613dea565b5b6040519080825280601f01601f19166020018201604052801561371a5781602001600182028036833780820191505090505b5090505f82602001820190505b60011561377b578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816137705761376f614649565b5b0494505f8503613727575b819350505050919050565b5f9392505050565b6137988383613976565b5f8373ffffffffffffffffffffffffffffffffffffffff163b14613820575f805490505f83820390505b6137d45f8683806001019450866134e1565b61380a576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106137c257815f541461381d575f80fd5b50505b505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613881577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161387757613876614649565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106138be576d04ee2d6d415b85acef810000000083816138b4576138b3614649565b5b0492506020810190505b662386f26fc1000083106138ed57662386f26fc1000083816138e3576138e2614649565b5b0492506010810190505b6305f5e1008310613916576305f5e100838161390c5761390b614649565b5b0492506008810190505b612710831061393b57612710838161393157613930614649565b5b0492506004810190505b6064831061395e576064838161395457613953614649565b5b0492506002810190505b600a831061396d576001810190505b80915050919050565b5f805490505f82036139b4576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6139c05f848385613303565b600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282540192505081905550613a3283613a235f865f613309565b613a2c85613b1f565b17613330565b60045f8381526020019081526020015f20819055505f80838301905073ffffffffffffffffffffffffffffffffffffffff8516915082825f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4600183015b818114613acc5780835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4600181019050613a93565b505f8203613b06576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805f819055505050613b1a5f84838561335a565b505050565b5f6001821460e11b9050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613b7381613b3f565b8114613b7d575f80fd5b50565b5f81359050613b8e81613b6a565b92915050565b5f60208284031215613ba957613ba8613b37565b5b5f613bb684828501613b80565b91505092915050565b5f8115159050919050565b613bd381613bbf565b82525050565b5f602082019050613bec5f830184613bca565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015613c29578082015181840152602081019050613c0e565b5f8484015250505050565b5f601f19601f8301169050919050565b5f613c4e82613bf2565b613c588185613bfc565b9350613c68818560208601613c0c565b613c7181613c34565b840191505092915050565b5f6020820190508181035f830152613c948184613c44565b905092915050565b5f819050919050565b613cae81613c9c565b8114613cb8575f80fd5b50565b5f81359050613cc981613ca5565b92915050565b5f60208284031215613ce457613ce3613b37565b5b5f613cf184828501613cbb565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f613d2382613cfa565b9050919050565b613d3381613d19565b82525050565b5f602082019050613d4c5f830184613d2a565b92915050565b613d5b81613d19565b8114613d65575f80fd5b50565b5f81359050613d7681613d52565b92915050565b5f8060408385031215613d9257613d91613b37565b5b5f613d9f85828601613d68565b9250506020613db085828601613cbb565b9150509250929050565b613dc381613c9c565b82525050565b5f602082019050613ddc5f830184613dba565b92915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b613e2082613c34565b810181811067ffffffffffffffff82111715613e3f57613e3e613dea565b5b80604052505050565b5f613e51613b2e565b9050613e5d8282613e17565b919050565b5f67ffffffffffffffff821115613e7c57613e7b613dea565b5b613e8582613c34565b9050602081019050919050565b828183375f83830152505050565b5f613eb2613ead84613e62565b613e48565b905082815260208101848484011115613ece57613ecd613de6565b5b613ed9848285613e92565b509392505050565b5f82601f830112613ef557613ef4613de2565b5b8135613f05848260208601613ea0565b91505092915050565b5f60208284031215613f2357613f22613b37565b5b5f82013567ffffffffffffffff811115613f4057613f3f613b3b565b5b613f4c84828501613ee1565b91505092915050565b5f805f60608486031215613f6c57613f6b613b37565b5b5f613f7986828701613d68565b9350506020613f8a86828701613d68565b9250506040613f9b86828701613cbb565b9150509250925092565b5f60208284031215613fba57613fb9613b37565b5b5f613fc784828501613d68565b91505092915050565b5f8060408385031215613fe657613fe5613b37565b5b5f613ff385828601613cbb565b925050602083013567ffffffffffffffff81111561401457614013613b3b565b5b61402085828601613ee1565b9150509250929050565b61403381613bbf565b811461403d575f80fd5b50565b5f8135905061404e8161402a565b92915050565b5f806040838503121561406a57614069613b37565b5b5f61407785828601613d68565b925050602061408885828601614040565b9150509250929050565b5f819050919050565b5f6140b56140b06140ab84613cfa565b614092565b613cfa565b9050919050565b5f6140c68261409b565b9050919050565b5f6140d7826140bc565b9050919050565b6140e7816140cd565b82525050565b5f6020820190506141005f8301846140de565b92915050565b5f67ffffffffffffffff8211156141205761411f613dea565b5b61412982613c34565b9050602081019050919050565b5f61414861414384614106565b613e48565b90508281526020810184848401111561416457614163613de6565b5b61416f848285613e92565b509392505050565b5f82601f83011261418b5761418a613de2565b5b813561419b848260208601614136565b91505092915050565b5f805f80608085870312156141bc576141bb613b37565b5b5f6141c987828801613d68565b94505060206141da87828801613d68565b93505060406141eb87828801613cbb565b925050606085013567ffffffffffffffff81111561420c5761420b613b3b565b5b61421887828801614177565b91505092959194509250565b5f6020828403121561423957614238613b37565b5b5f61424684828501614040565b91505092915050565b5f806040838503121561426557614264613b37565b5b5f61427285828601613d68565b925050602061428385828601613d68565b9150509250929050565b5f80604083850312156142a3576142a2613b37565b5b5f6142b085828601613cbb565b92505060206142c185828601613d68565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061430f57607f821691505b602082108103614322576143216142cb565b5b50919050565b5f81905092915050565b5f61433c82613bf2565b6143468185614328565b9350614356818560208601613c0c565b80840191505092915050565b5f61436d8284614332565b915081905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026143d47fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614399565b6143de8683614399565b95508019841693508086168417925050509392505050565b5f61441061440b61440684613c9c565b614092565b613c9c565b9050919050565b5f819050919050565b614429836143f6565b61443d61443582614417565b8484546143a5565b825550505050565b5f90565b614451614445565b61445c818484614420565b505050565b5b8181101561447f576144745f82614449565b600181019050614462565b5050565b601f8211156144c45761449581614378565b61449e8461438a565b810160208510156144ad578190505b6144c16144b98561438a565b830182614461565b50505b505050565b5f82821c905092915050565b5f6144e45f19846008026144c9565b1980831691505092915050565b5f6144fc83836144d5565b9150826002028217905092915050565b61451582613bf2565b67ffffffffffffffff81111561452e5761452d613dea565b5b61453882546142f8565b614543828285614483565b5f60209050601f831160018114614574575f8415614562578287015190505b61456c85826144f1565b8655506145d3565b601f19841661458286614378565b5f5b828110156145a957848901518255600182019150602085019450602081019050614584565b868310156145c657848901516145c2601f8916826144d5565b8355505b6001600288020188555050505b505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61461282613c9c565b915061461d83613c9c565b925082820261462b81613c9c565b91508282048414831517614642576146416145db565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61468082613c9c565b915061468b83613c9c565b92508261469b5761469a614649565b5b828204905092915050565b5f81905092915050565b50565b5f6146be5f836146a6565b91506146c9826146b0565b5f82019050919050565b5f6146dd826146b3565b9150819050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746865206f776e6572005f82015250565b5f61471b601f83613bfc565b9150614726826146e7565b602082019050919050565b5f6020820190508181035f8301526147488161470f565b9050919050565b7f4e6f7420612076616c6964206e6577206e616d650000000000000000000000005f82015250565b5f614783601483613bfc565b915061478e8261474f565b602082019050919050565b5f6020820190508181035f8301526147b081614777565b9050919050565b5f819050815f5260205f209050919050565b5f81546147d5816142f8565b6147df81866146a6565b9450600182165f81146147f9576001811461480e57614840565b60ff1983168652811515820286019350614840565b614817856147b7565b5f5b8381101561483857815481890152600182019150602081019050614819565b838801955050505b50505092915050565b5f61485482846147c9565b915081905092915050565b5f819050919050565b6148718161485f565b811461487b575f80fd5b50565b5f8151905061488c81614868565b92915050565b5f602082840312156148a7576148a6613b37565b5b5f6148b48482850161487e565b91505092915050565b5f81519050919050565b5f6148d1826148bd565b6148db81856146a6565b93506148eb818560208601613c0c565b80840191505092915050565b5f61490282846148c7565b915081905092915050565b7f4e6577206e616d652069732073616d65206173207468652063757272656e74205f8201527f6f6e650000000000000000000000000000000000000000000000000000000000602082015250565b5f614967602383613bfc565b91506149728261490d565b604082019050919050565b5f6020820190508181035f8301526149948161495b565b9050919050565b7f4e616d6520616c726561647920726573657276656400000000000000000000005f82015250565b5f6149cf601583613bfc565b91506149da8261499b565b602082019050919050565b5f6020820190508181035f8301526149fc816149c3565b9050919050565b7f43616c6c6572206973206e6f7420746865204d6f64657261746f7200000000005f82015250565b5f614a37601b83613bfc565b9150614a4282614a03565b602082019050919050565b5f6020820190508181035f830152614a6481614a2b565b9050919050565b7f496e73756666696369656e742066756e647321000000000000000000000000005f82015250565b5f614a9f601383613bfc565b9150614aaa82614a6b565b602082019050919050565b5f6020820190508181035f830152614acc81614a93565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f60ff82169050919050565b5f614b1682614b00565b9150614b2183614b00565b9250828201905060ff811115614b3a57614b396145db565b5b92915050565b5f614b4a82613c9c565b9150614b5583613c9c565b9250828203905081811115614b6d57614b6c6145db565b5b92915050565b5f614b7d82613c9c565b9150614b8883613c9c565b9250828201905080821115614ba057614b9f6145db565b5b92915050565b7f4d617820737570706c79206578636565646564210000000000000000000000005f82015250565b5f614bda601483613bfc565b9150614be582614ba6565b602082019050919050565b5f6020820190508181035f830152614c0781614bce565b9050919050565b7f53616c6520686173206e6f7420737461727465640000000000000000000000005f82015250565b5f614c42601483613bfc565b9150614c4d82614c0e565b602082019050919050565b5f6020820190508181035f830152614c6f81614c36565b9050919050565b7f496e76616c6964206d696e7420616d6f756e74210000000000000000000000005f82015250565b5f614caa601483613bfc565b9150614cb582614c76565b602082019050919050565b5f6020820190508181035f830152614cd781614c9e565b9050919050565b5f606082019050614cf15f830186613d2a565b614cfe6020830185613d2a565b614d0b6040830184613dba565b949350505050565b5f81519050614d218161402a565b92915050565b5f60208284031215614d3c57614d3b613b37565b5b5f614d4984828501614d13565b91505092915050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f5f8201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b5f614dac602f83613bfc565b9150614db782614d52565b604082019050919050565b5f6020820190508181035f830152614dd981614da0565b9050919050565b5f8154614dec816142f8565b614df68186614328565b9450600182165f8114614e105760018114614e2557614e57565b60ff1983168652811515820286019350614e57565b614e2e85614378565b5f5b83811015614e4f57815481890152600182019150602081019050614e30565b838801955050505b50505092915050565b5f614e6b8286614332565b9150614e778285614332565b9150614e838284614de0565b9150819050949350505050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f614ec4601f83613bfc565b9150614ecf82614e90565b602082019050919050565b5f6020820190508181035f830152614ef181614eb8565b9050919050565b5f82825260208201905092915050565b5f614f12826148bd565b614f1c8185614ef8565b9350614f2c818560208601613c0c565b614f3581613c34565b840191505092915050565b5f608082019050614f535f830187613d2a565b614f606020830186613d2a565b614f6d6040830185613dba565b8181036060830152614f7f8184614f08565b905095945050505050565b5f81519050614f9881613b6a565b92915050565b5f60208284031215614fb357614fb2613b37565b5b5f614fc084828501614f8a565b9150509291505056fea2646970667358221220cf2a693f2fe409cf0f171578f1218cc405c5f5ebc7f05c7ee5aaef7d96ea4ab364736f6c63430008170033
Verified Source Code Partial Match
Compiler: v0.8.23+commit.f704f362
EVM: shanghai
Optimization: No
PREMECuddleBuddies.sol 2724 lines
// File: erc721a/contracts/IERC721A.sol
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs
pragma solidity ^0.8.4;
/**
* @dev Interface of ERC721A.
*/
interface IERC721A {
/**
* The caller must own the token or be an approved operator.
*/
error ApprovalCallerNotOwnerNorApproved();
/**
* The token does not exist.
*/
error ApprovalQueryForNonexistentToken();
/**
* Cannot query the balance for the zero address.
*/
error BalanceQueryForZeroAddress();
/**
* Cannot mint to the zero address.
*/
error MintToZeroAddress();
/**
* The quantity of tokens minted must be more than zero.
*/
error MintZeroQuantity();
/**
* The token does not exist.
*/
error OwnerQueryForNonexistentToken();
/**
* The caller must own the token or be an approved operator.
*/
error TransferCallerNotOwnerNorApproved();
/**
* The token must be owned by `from`.
*/
error TransferFromIncorrectOwner();
/**
* Cannot safely transfer to a contract that does not implement the
* ERC721Receiver interface.
*/
error TransferToNonERC721ReceiverImplementer();
/**
* Cannot transfer to the zero address.
*/
error TransferToZeroAddress();
/**
* The token does not exist.
*/
error URIQueryForNonexistentToken();
/**
* The `quantity` minted with ERC2309 exceeds the safety limit.
*/
error MintERC2309QuantityExceedsLimit();
/**
* The `extraData` cannot be set on an unintialized ownership slot.
*/
error OwnershipNotInitializedForExtraData();
// =============================================================
// STRUCTS
// =============================================================
struct TokenOwnership {
// The address of the owner.
address addr;
// Stores the start time of ownership with minimal overhead for tokenomics.
uint64 startTimestamp;
// Whether the token has been burned.
bool burned;
// Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
uint24 extraData;
}
// =============================================================
// TOKEN COUNTERS
// =============================================================
/**
* @dev Returns the total number of tokens in existence.
* Burned tokens will reduce the count.
* To get the total number of tokens minted, please see {_totalMinted}.
*/
function totalSupply() external view returns (uint256);
// =============================================================
// IERC165
// =============================================================
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
* to learn more about how these ids are created.
*
* This function call must use less than 30000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
// =============================================================
// IERC721
// =============================================================
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables
* (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in `owner`'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`,
* checking first that contract recipients are aware of the ERC721 protocol
* to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move
* this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement
* {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external payable;
/**
* @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external payable;
/**
* @dev Transfers `tokenId` from `from` to `to`.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom}
* whenever possible.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token
* by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external payable;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the
* zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external payable;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom}
* for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
// =============================================================
// IERC721Metadata
// =============================================================
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
// =============================================================
// IERC2309
// =============================================================
/**
* @dev Emitted when tokens in `fromTokenId` to `toTokenId`
* (inclusive) is transferred from `from` to `to`, as defined in the
* [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
*
* See {_mintERC2309} for more details.
*/
event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}
// File: erc721a/contracts/ERC721A.sol
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs
pragma solidity ^0.8.4;
/**
* @dev Interface of ERC721 token receiver.
*/
interface ERC721A__IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
/**
* @title ERC721A
*
* @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
* Non-Fungible Token Standard, including the Metadata extension.
* Optimized for lower gas during batch mints.
*
* Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
* starting from `_startTokenId()`.
*
* Assumptions:
*
* - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
* - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
*/
contract ERC721A is IERC721A {
// Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364).
struct TokenApprovalRef {
address value;
}
// =============================================================
// CONSTANTS
// =============================================================
// Mask of an entry in packed address data.
uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;
// The bit position of `numberMinted` in packed address data.
uint256 private constant _BITPOS_NUMBER_MINTED = 64;
// The bit position of `numberBurned` in packed address data.
uint256 private constant _BITPOS_NUMBER_BURNED = 128;
// The bit position of `aux` in packed address data.
uint256 private constant _BITPOS_AUX = 192;
// Mask of all 256 bits in packed address data except the 64 bits for `aux`.
uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;
// The bit position of `startTimestamp` in packed ownership.
uint256 private constant _BITPOS_START_TIMESTAMP = 160;
// The bit mask of the `burned` bit in packed ownership.
uint256 private constant _BITMASK_BURNED = 1 << 224;
// The bit position of the `nextInitialized` bit in packed ownership.
uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;
// The bit mask of the `nextInitialized` bit in packed ownership.
uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225;
// The bit position of `extraData` in packed ownership.
uint256 private constant _BITPOS_EXTRA_DATA = 232;
// Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;
// The mask of the lower 160 bits for addresses.
uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;
// The maximum `quantity` that can be minted with {_mintERC2309}.
// This limit is to prevent overflows on the address data entries.
// For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
// is required to cause an overflow, which is unrealistic.
uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;
// The `Transfer` event signature is given by:
// `keccak256(bytes("Transfer(address,address,uint256)"))`.
bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;
// =============================================================
// STORAGE
// =============================================================
// The next token ID to be minted.
uint256 private _currentIndex;
// The number of tokens burned.
uint256 private _burnCounter;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to ownership details
// An empty struct value does not necessarily mean the token is unowned.
// See {_packedOwnershipOf} implementation for details.
//
// Bits Layout:
// - [0..159] `addr`
// - [160..223] `startTimestamp`
// - [224] `burned`
// - [225] `nextInitialized`
// - [232..255] `extraData`
mapping(uint256 => uint256) private _packedOwnerships;
// Mapping owner address to address data.
//
// Bits Layout:
// - [0..63] `balance`
// - [64..127] `numberMinted`
// - [128..191] `numberBurned`
// - [192..255] `aux`
mapping(address => uint256) private _packedAddressData;
// Mapping from token ID to approved address.
mapping(uint256 => TokenApprovalRef) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
// =============================================================
// CONSTRUCTOR
// =============================================================
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
_currentIndex = _startTokenId();
}
// =============================================================
// TOKEN COUNTING OPERATIONS
// =============================================================
/**
* @dev Returns the starting token ID.
* To change the starting token ID, please override this function.
*/
function _startTokenId() internal view virtual returns (uint256) {
return 0;
}
/**
* @dev Returns the next token ID to be minted.
*/
function _nextTokenId() internal view virtual returns (uint256) {
return _currentIndex;
}
/**
* @dev Returns the total number of tokens in existence.
* Burned tokens will reduce the count.
* To get the total number of tokens minted, please see {_totalMinted}.
*/
function totalSupply() public view virtual override returns (uint256) {
// Counter underflow is impossible as _burnCounter cannot be incremented
// more than `_currentIndex - _startTokenId()` times.
unchecked {
return _currentIndex - _burnCounter - _startTokenId();
}
}
/**
* @dev Returns the total amount of tokens minted in the contract.
*/
function _totalMinted() internal view virtual returns (uint256) {
// Counter underflow is impossible as `_currentIndex` does not decrement,
// and it is initialized to `_startTokenId()`.
unchecked {
return _currentIndex - _startTokenId();
}
}
/**
* @dev Returns the total number of tokens burned.
*/
function _totalBurned() internal view virtual returns (uint256) {
return _burnCounter;
}
// =============================================================
// ADDRESS DATA OPERATIONS
// =============================================================
/**
* @dev Returns the number of tokens in `owner`'s account.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
if (owner == address(0)) revert BalanceQueryForZeroAddress();
return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
}
/**
* Returns the number of tokens minted by `owner`.
*/
function _numberMinted(address owner) internal view returns (uint256) {
return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY;
}
/**
* Returns the number of tokens burned by or on behalf of `owner`.
*/
function _numberBurned(address owner) internal view returns (uint256) {
return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY;
}
/**
* Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
*/
function _getAux(address owner) internal view returns (uint64) {
return uint64(_packedAddressData[owner] >> _BITPOS_AUX);
}
/**
* Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
* If there are multiple variables, please pack them into a uint64.
*/
function _setAux(address owner, uint64 aux) internal virtual {
uint256 packed = _packedAddressData[owner];
uint256 auxCasted;
// Cast `aux` with assembly to avoid redundant masking.
assembly {
auxCasted := aux
}
packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
_packedAddressData[owner] = packed;
}
// =============================================================
// IERC165
// =============================================================
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
* to learn more about how these ids are created.
*
* This function call must use less than 30000 gas.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
// The interface IDs are constants representing the first 4 bytes
// of the XOR of all function selectors in the interface.
// See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
// (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
return
interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
}
// =============================================================
// IERC721Metadata
// =============================================================
/**
* @dev Returns the token collection name.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the token collection symbol.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
string memory baseURI = _baseURI();
return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, it can be overridden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return '';
}
// =============================================================
// OWNERSHIPS OPERATIONS
// =============================================================
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
return address(uint160(_packedOwnershipOf(tokenId)));
}
/**
* @dev Gas spent here starts off proportional to the maximum mint batch size.
* It gradually moves to O(1) as tokens get transferred around over time.
*/
function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) {
return _unpackedOwnership(_packedOwnershipOf(tokenId));
}
/**
* @dev Returns the unpacked `TokenOwnership` struct at `index`.
*/
function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) {
return _unpackedOwnership(_packedOwnerships[index]);
}
/**
* @dev Initializes the ownership slot minted at `index` for efficiency purposes.
*/
function _initializeOwnershipAt(uint256 index) internal virtual {
if (_packedOwnerships[index] == 0) {
_packedOwnerships[index] = _packedOwnershipOf(index);
}
}
/**
* Returns the packed ownership data of `tokenId`.
*/
function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
uint256 curr = tokenId;
unchecked {
if (_startTokenId() <= curr)
if (curr < _currentIndex) {
uint256 packed = _packedOwnerships[curr];
// If not burned.
if (packed & _BITMASK_BURNED == 0) {
// Invariant:
// There will always be an initialized ownership slot
// (i.e. `ownership.addr != address(0) && ownership.burned == false`)
// before an unintialized ownership slot
// (i.e. `ownership.addr == address(0) && ownership.burned == false`)
// Hence, `curr` will not underflow.
//
// We can directly compare the packed value.
// If the address is zero, packed will be zero.
while (packed == 0) {
packed = _packedOwnerships[--curr];
}
return packed;
}
}
}
revert OwnerQueryForNonexistentToken();
}
/**
* @dev Returns the unpacked `TokenOwnership` struct from `packed`.
*/
function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
ownership.addr = address(uint160(packed));
ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
ownership.burned = packed & _BITMASK_BURNED != 0;
ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
}
/**
* @dev Packs ownership data into a single uint256.
*/
function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
assembly {
// Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
owner := and(owner, _BITMASK_ADDRESS)
// `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`.
result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
}
}
/**
* @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
*/
function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
// For branchless setting of the `nextInitialized` flag.
assembly {
// `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`.
result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
}
}
// =============================================================
// APPROVAL OPERATIONS
// =============================================================
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the
* zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) public payable virtual override {
address owner = ownerOf(tokenId);
if (_msgSenderERC721A() != owner)
if (!isApprovedForAll(owner, _msgSenderERC721A())) {
revert ApprovalCallerNotOwnerNorApproved();
}
_tokenApprovals[tokenId].value = to;
emit Approval(owner, to, tokenId);
}
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();
return _tokenApprovals[tokenId].value;
}
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom}
* for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_operatorApprovals[_msgSenderERC721A()][operator] = approved;
emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
}
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted. See {_mint}.
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return
_startTokenId() <= tokenId &&
tokenId < _currentIndex && // If within bounds,
_packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned.
}
/**
* @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
*/
function _isSenderApprovedOrOwner(
address approvedAddress,
address owner,
address msgSender
) private pure returns (bool result) {
assembly {
// Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
owner := and(owner, _BITMASK_ADDRESS)
// Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
msgSender := and(msgSender, _BITMASK_ADDRESS)
// `msgSender == owner || msgSender == approvedAddress`.
result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
}
}
/**
* @dev Returns the storage slot and value for the approved address of `tokenId`.
*/
function _getApprovedSlotAndAddress(uint256 tokenId)
private
view
returns (uint256 approvedAddressSlot, address approvedAddress)
{
TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
// The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`.
assembly {
approvedAddressSlot := tokenApproval.slot
approvedAddress := sload(approvedAddressSlot)
}
}
// =============================================================
// TRANSFER OPERATIONS
// =============================================================
/**
* @dev Transfers `tokenId` from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token
* by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public payable virtual override {
uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();
(uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);
// The nested ifs save around 20+ gas over a compound boolean condition.
if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
if (to == address(0)) revert TransferToZeroAddress();
_beforeTokenTransfers(from, to, tokenId, 1);
// Clear approvals from the previous owner.
assembly {
if approvedAddress {
// This is equivalent to `delete _tokenApprovals[tokenId]`.
sstore(approvedAddressSlot, 0)
}
}
// Underflow of the sender's balance is impossible because we check for
// ownership above and the recipient's balance can't realistically overflow.
// Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
unchecked {
// We can directly increment and decrement the balances.
--_packedAddressData[from]; // Updates: `balance -= 1`.
++_packedAddressData[to]; // Updates: `balance += 1`.
// Updates:
// - `address` to the next owner.
// - `startTimestamp` to the timestamp of transfering.
// - `burned` to `false`.
// - `nextInitialized` to `true`.
_packedOwnerships[tokenId] = _packOwnershipData(
to,
_BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
);
// If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
uint256 nextTokenId = tokenId + 1;
// If the next slot's address is zero and not burned (i.e. packed value is zero).
if (_packedOwnerships[nextTokenId] == 0) {
// If the next slot is within bounds.
if (nextTokenId != _currentIndex) {
// Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
_packedOwnerships[nextTokenId] = prevOwnershipPacked;
}
}
}
}
emit Transfer(from, to, tokenId);
_afterTokenTransfers(from, to, tokenId, 1);
}
/**
* @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public payable virtual override {
safeTransferFrom(from, to, tokenId, '');
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token
* by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement
* {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public payable virtual override {
transferFrom(from, to, tokenId);
if (to.code.length != 0)
if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
}
/**
* @dev Hook that is called before a set of serially-ordered token IDs
* are about to be transferred. This includes minting.
* And also called before burning one token.
*
* `startTokenId` - the first token ID to be transferred.
* `quantity` - the amount to be transferred.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, `tokenId` will be burned by `from`.
* - `from` and `to` are never both zero.
*/
function _beforeTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual {}
/**
* @dev Hook that is called after a set of serially-ordered token IDs
* have been transferred. This includes minting.
* And also called after one token has been burned.
*
* `startTokenId` - the first token ID to be transferred.
* `quantity` - the amount to be transferred.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
* transferred to `to`.
* - When `from` is zero, `tokenId` has been minted for `to`.
* - When `to` is zero, `tokenId` has been burned by `from`.
* - `from` and `to` are never both zero.
*/
function _afterTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual {}
/**
* @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
*
* `from` - Previous owner of the given token ID.
* `to` - Target address that will receive the token.
* `tokenId` - Token ID to be transferred.
* `_data` - Optional data to send along with the call.
*
* Returns whether the call correctly returned the expected magic value.
*/
function _checkContractOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
bytes4 retval
) {
return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert TransferToNonERC721ReceiverImplementer();
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
// =============================================================
// MINT OPERATIONS
// =============================================================
/**
* @dev Mints `quantity` tokens and transfers them to `to`.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `quantity` must be greater than 0.
*
* Emits a {Transfer} event for each mint.
*/
function _mint(address to, uint256 quantity) internal virtual {
uint256 startTokenId = _currentIndex;
if (quantity == 0) revert MintZeroQuantity();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
// Overflows are incredibly unrealistic.
// `balance` and `numberMinted` have a maximum limit of 2**64.
// `tokenId` has a maximum limit of 2**256.
unchecked {
// Updates:
// - `balance += quantity`.
// - `numberMinted += quantity`.
//
// We can directly add to the `balance` and `numberMinted`.
_packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);
// Updates:
// - `address` to the owner.
// - `startTimestamp` to the timestamp of minting.
// - `burned` to `false`.
// - `nextInitialized` to `quantity == 1`.
_packedOwnerships[startTokenId] = _packOwnershipData(
to,
_nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
);
uint256 toMasked;
uint256 end = startTokenId + quantity;
// Use assembly to loop and emit the `Transfer` event for gas savings.
// The duplicated `log4` removes an extra check and reduces stack juggling.
// The assembly, together with the surrounding Solidity code, have been
// delicately arranged to nudge the compiler into producing optimized opcodes.
assembly {
// Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
toMasked := and(to, _BITMASK_ADDRESS)
// Emit the `Transfer` event.
log4(
0, // Start of data (0, since no data).
0, // End of data (0, since no data).
_TRANSFER_EVENT_SIGNATURE, // Signature.
0, // `address(0)`.
toMasked, // `to`.
startTokenId // `tokenId`.
)
// The `iszero(eq(,))` check ensures that large values of `quantity`
// that overflows uint256 will make the loop run out of gas.
// The compiler will optimize the `iszero` away for performance.
for {
let tokenId := add(startTokenId, 1)
} iszero(eq(tokenId, end)) {
tokenId := add(tokenId, 1)
} {
// Emit the `Transfer` event. Similar to above.
log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
}
}
if (toMasked == 0) revert MintToZeroAddress();
_currentIndex = end;
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
/**
* @dev Mints `quantity` tokens and transfers them to `to`.
*
* This function is intended for efficient minting only during contract creation.
*
* It emits only one {ConsecutiveTransfer} as defined in
* [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
* instead of a sequence of {Transfer} event(s).
*
* Calling this function outside of contract creation WILL make your contract
* non-compliant with the ERC721 standard.
* For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
* {ConsecutiveTransfer} event is only permissible during contract creation.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `quantity` must be greater than 0.
*
* Emits a {ConsecutiveTransfer} event.
*/
function _mintERC2309(address to, uint256 quantity) internal virtual {
uint256 startTokenId = _currentIndex;
if (to == address(0)) revert MintToZeroAddress();
if (quantity == 0) revert MintZeroQuantity();
if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
// Overflows are unrealistic due to the above check for `quantity` to be below the limit.
unchecked {
// Updates:
// - `balance += quantity`.
// - `numberMinted += quantity`.
//
// We can directly add to the `balance` and `numberMinted`.
_packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);
// Updates:
// - `address` to the owner.
// - `startTimestamp` to the timestamp of minting.
// - `burned` to `false`.
// - `nextInitialized` to `quantity == 1`.
_packedOwnerships[startTokenId] = _packOwnershipData(
to,
_nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
);
emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);
_currentIndex = startTokenId + quantity;
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
/**
* @dev Safely mints `quantity` tokens and transfers them to `to`.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement
* {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
* - `quantity` must be greater than 0.
*
* See {_mint}.
*
* Emits a {Transfer} event for each mint.
*/
function _safeMint(
address to,
uint256 quantity,
bytes memory _data
) internal virtual {
_mint(to, quantity);
unchecked {
if (to.code.length != 0) {
uint256 end = _currentIndex;
uint256 index = end - quantity;
do {
if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
} while (index < end);
// Reentrancy protection.
if (_currentIndex != end) revert();
}
}
}
/**
* @dev Equivalent to `_safeMint(to, quantity, '')`.
*/
function _safeMint(address to, uint256 quantity) internal virtual {
_safeMint(to, quantity, '');
}
// =============================================================
// BURN OPERATIONS
// =============================================================
/**
* @dev Equivalent to `_burn(tokenId, false)`.
*/
function _burn(uint256 tokenId) internal virtual {
_burn(tokenId, false);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
address from = address(uint160(prevOwnershipPacked));
(uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);
if (approvalCheck) {
// The nested ifs save around 20+ gas over a compound boolean condition.
if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
}
_beforeTokenTransfers(from, address(0), tokenId, 1);
// Clear approvals from the previous owner.
assembly {
if approvedAddress {
// This is equivalent to `delete _tokenApprovals[tokenId]`.
sstore(approvedAddressSlot, 0)
}
}
// Underflow of the sender's balance is impossible because we check for
// ownership above and the recipient's balance can't realistically overflow.
// Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
unchecked {
// Updates:
// - `balance -= 1`.
// - `numberBurned += 1`.
//
// We can directly decrement the balance, and increment the number burned.
// This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`.
_packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1;
// Updates:
// - `address` to the last owner.
// - `startTimestamp` to the timestamp of burning.
// - `burned` to `true`.
// - `nextInitialized` to `true`.
_packedOwnerships[tokenId] = _packOwnershipData(
from,
(_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
);
// If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
uint256 nextTokenId = tokenId + 1;
// If the next slot's address is zero and not burned (i.e. packed value is zero).
if (_packedOwnerships[nextTokenId] == 0) {
// If the next slot is within bounds.
if (nextTokenId != _currentIndex) {
// Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
_packedOwnerships[nextTokenId] = prevOwnershipPacked;
}
}
}
}
emit Transfer(from, address(0), tokenId);
_afterTokenTransfers(from, address(0), tokenId, 1);
// Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
unchecked {
_burnCounter++;
}
}
// =============================================================
// EXTRA DATA OPERATIONS
// =============================================================
/**
* @dev Directly sets the extra data for the ownership data `index`.
*/
function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
uint256 packed = _packedOwnerships[index];
if (packed == 0) revert OwnershipNotInitializedForExtraData();
uint256 extraDataCasted;
// Cast `extraData` with assembly to avoid redundant masking.
assembly {
extraDataCasted := extraData
}
packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
_packedOwnerships[index] = packed;
}
/**
* @dev Called during each token transfer to set the 24bit `extraData` field.
* Intended to be overridden by the cosumer contract.
*
* `previousExtraData` - the value of `extraData` before transfer.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, `tokenId` will be burned by `from`.
* - `from` and `to` are never both zero.
*/
function _extraData(
address from,
address to,
uint24 previousExtraData
) internal view virtual returns (uint24) {}
/**
* @dev Returns the next extra data for the packed ownership data.
* The returned result is shifted into position.
*/
function _nextExtraData(
address from,
address to,
uint256 prevOwnershipPacked
) private view returns (uint256) {
uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
}
// =============================================================
// OTHER OPERATIONS
// =============================================================
/**
* @dev Returns the message sender (defaults to `msg.sender`).
*
* If you are writing GSN compatible contracts, you need to override this function.
*/
function _msgSenderERC721A() internal view virtual returns (address) {
return msg.sender;
}
/**
* @dev Converts a uint256 to its ASCII string decimal representation.
*/
function _toString(uint256 value) internal pure virtual returns (string memory str) {
assembly {
// The maximum value of a uint256 contains 78 digits (1 byte per digit), but
// we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
// We will need...
// [truncated — 97966 bytes total]
Read Contract
MaxNFTSupply 0x54c6191d → uint256
Moderator 0x6bf8a5f6 → address
NameChangePrice 0xd8a7de1e → uint256
NameChangePriceETH 0xa675ca2f → uint256
SaleStartTimestamp 0x99b1755b → uint256
balanceOf 0x70a08231 → uint256
burnaddress 0xe5c5f1d5 → address
burntoken 0xb42f0fb8 → address
cost 0x13faede6 → uint256
getApproved 0x081812fc → address
hiddenMetadataUri 0xa45ba8e7 → string
isApprovedForAll 0xe985e9c5 → bool
isNameReserved 0x15b56d10 → bool
maxMintAmountPerTx 0x94354fd0 → uint256
name 0x06fdde03 → string
owner 0x8da5cb5b → address
ownerOf 0x6352211e → address
percentage 0xc78ad77f → uint256
revealed 0x51830227 → bool
supportsInterface 0x01ffc9a7 → bool
symbol 0x95d89b41 → string
toLower 0x9416b423 → string
tokenNameByIndex 0x6d522418 → string
tokenURI 0xc87b56dd → string
totalSupply 0x18160ddd → uint256
uriPrefix 0x62b99ad4 → string
uriSuffix 0x5503a0e8 → string
validateName 0x9ffdb65a → bool
Write Contract 28 functions
These functions modify contract state and require a wallet transaction to execute.
approve 0x095ea7b3
address to
uint256 tokenId
changeModerator 0x46642921
address _Moderator
changeName 0xc39cbef1
uint256 tokenId
string newName
changeNameDev 0x65657c41
uint256 tokenId
string newName
changeNameETH 0x7ec7e7a4
uint256 tokenId
string newName
mint 0xa0712d68
uint256 _mintAmount
mintForAddress 0xefbd73f4
uint256 _mintAmount
address _receiver
renounceOwnership 0x715018a6
No parameters
safeTransferFrom 0x42842e0e
address from
address to
uint256 tokenId
safeTransferFrom 0xb88d4fde
address from
address to
uint256 tokenId
bytes _data
setApprovalForAll 0xa22cb465
address operator
bool approved
setBurnaddress 0x8c0f66db
address _burnaddress
setBurntoken 0x32744e3a
address _burntokenaddress
setHiddenMetadataUri 0x4fdd43cb
string _hiddenMetadataUri
setMaxMintAmountPerTx 0xb071401b
uint256 _maxMintAmountPerTx
setMintPrice 0xf4a0a528
uint256 _MintPrice
setNameChangePrice 0x84a1b902
uint256 _NameChangePrice
setNameChangePriceETH 0xb8c489e1
uint256 _NameChangePriceETH
setPayoutaddress1 0x3ebee8f5
address _payoutaddress1
setPayoutaddress2 0x55c8d840
address _payoutaddress2
setPercentage 0x5da4a1d3
uint256 _percentage
setRevealed 0xe0a80853
bool _state
setSaleStartTimestamp 0x3db82fb5
uint256 _SaleStartTimestamp
setUriPrefix 0x7ec4a659
string _uriPrefix
setUriSuffix 0x16ba10e0
string _uriSuffix
transferFrom 0x23b872dd
address from
address to
uint256 tokenId
transferOwnership 0xf2fde38b
address newOwner
withdraw 0x3ccfd60b
No parameters
Recent Transactions
No transactions found for this address