Address Contract Verified
Address
0x864D6DC00d4432007E894Da6a9DB95EE1178DAB7
Balance
0 ETH
Nonce
1
Code Size
20032 bytes
Creator
0x9c959f67...8E62 at tx 0x89bacb4f...fcf5bb
Indexed Transactions
0
Contract Bytecode
20032 bytes
0x6080604052600436106102305760003560e01c806370a082311161012e578063c87b56dd116100ab578063efd0cbf91161006f578063efd0cbf914610848578063f2fde38b14610864578063f3fef3a31461088d578063f5aa406d146108b6578063fc1a1c36146108df57610230565b8063c87b56dd1461074f578063c95d83c61461078c578063cfe1908d146107b5578063d5abeb01146107e0578063e985e9c51461080b57610230565b8063a22cb465116100f2578063a22cb4651461068d578063a945bf80146106b6578063b88d4fde146106e1578063bc63f02e1461070a578063c62752551461072657610230565b806370a08231146105a6578063717d57d3146105e35780637e9845f51461060c5780638da5cb5b1461063757806395d89b411461066257610230565b80633a602b4d116101bc5780635a67de07116101805780635a67de07146104c1578063603f4d52146104ea5780636352211e1461051557806366cc5f0d146105525780636f8b44b01461057d57610230565b80633a602b4d146103d957806342842e0e1461041657806344d843811461043f5780634f6ccce71461045b57806355f804b31461049857610230565b8063095ea7b311610203578063095ea7b31461030357806318160ddd1461032c57806323b872dd1461035757806328bb1a2e146103805780632f745c591461039c57610230565b806301ffc9a71461023557806302c366bc1461027257806306fdde031461029b578063081812fc146102c6575b600080fd5b34801561024157600080fd5b5061025c60048036038101906102579190613894565b61090a565b60405161026991906138dc565b60405180910390f35b34801561027e57600080fd5b506102996004803603810190610294919061392d565b610aac565b005b3480156102a757600080fd5b506102b0610b33565b6040516102bd91906139ea565b60405180910390f35b3480156102d257600080fd5b506102ed60048036038101906102e8919061392d565b610bc1565b6040516102fa9190613a4d565b60405180910390f35b34801561030f57600080fd5b5061032a60048036038101906103259190613a94565b610bf4565b005b34801561033857600080fd5b50610341610dcb565b60405161034e9190613ae3565b60405180910390f35b34801561036357600080fd5b5061037e60048036038101906103799190613afe565b610dda565b005b61039a60048036038101906103959190613ccf565b610fbc565b005b3480156103a857600080fd5b506103c360048036038101906103be9190613a94565b611300565b6040516103d09190613ae3565b60405180910390f35b3480156103e557600080fd5b5061040060048036038101906103fb9190613d18565b6113eb565b60405161040d9190613ae3565b60405180910390f35b34801561042257600080fd5b5061043d60048036038101906104389190613afe565b611403565b005b61045960048036038101906104549190613ccf565b6115e5565b005b34801561046757600080fd5b50610482600480360381019061047d919061392d565b611929565b60405161048f9190613ae3565b60405180910390f35b3480156104a457600080fd5b506104bf60048036038101906104ba9190613dfa565b61198a565b005b3480156104cd57600080fd5b506104e860048036038101906104e39190613e68565b611a13565b005b3480156104f657600080fd5b506104ff611abd565b60405161050c9190613f0c565b60405180910390f35b34801561052157600080fd5b5061053c6004803603810190610537919061392d565b611ad0565b6040516105499190613a4d565b60405180910390f35b34801561055e57600080fd5b50610567611b2e565b6040516105749190613ae3565b60405180910390f35b34801561058957600080fd5b506105a4600480360381019061059f919061392d565b611b34565b005b3480156105b257600080fd5b506105cd60048036038101906105c89190613d18565b611c4e565b6040516105da9190613ae3565b60405180910390f35b3480156105ef57600080fd5b5061060a6004803603810190610605919061392d565b611c60565b005b34801561061857600080fd5b50610621611ce7565b60405161062e9190613ae3565b60405180910390f35b34801561064357600080fd5b5061064c611cfd565b6040516106599190613a4d565b60405180910390f35b34801561066e57600080fd5b50610677611d27565b60405161068491906139ea565b60405180910390f35b34801561069957600080fd5b506106b460048036038101906106af9190613f53565b611db5565b005b3480156106c257600080fd5b506106cb611f28565b6040516106d89190613ae3565b60405180910390f35b3480156106ed57600080fd5b5061070860048036038101906107039190614034565b611f2e565b005b610724600480360381019061071f91906140b7565b612113565b005b34801561073257600080fd5b5061074d6004803603810190610748919061392d565b612269565b005b34801561075b57600080fd5b506107766004803603810190610771919061392d565b6122f0565b60405161078391906139ea565b60405180910390f35b34801561079857600080fd5b506107b360048036038101906107ae919061392d565b612395565b005b3480156107c157600080fd5b506107ca61241c565b6040516107d79190613ae3565b60405180910390f35b3480156107ec57600080fd5b506107f5612422565b6040516108029190613ae3565b60405180910390f35b34801561081757600080fd5b50610832600480360381019061082d91906140f7565b612428565b60405161083f91906138dc565b60405180910390f35b610862600480360381019061085d919061392d565b61243c565b005b34801561087057600080fd5b5061088b60048036038101906108869190613d18565b6126c0565b005b34801561089957600080fd5b506108b460048036038101906108af9190613a94565b612803565b005b3480156108c257600080fd5b506108dd60048036038101906108d89190614137565b6129c3565b005b3480156108eb57600080fd5b506108f4612a4a565b6040516109019190613ae3565b60405180910390f35b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109d557507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a3d57507f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610aa557507f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60003390508073ffffffffffffffffffffffffffffffffffffffff16610ad0611cfd565b73ffffffffffffffffffffffffffffffffffffffff1614610b2857806040517f55932a1b000000000000000000000000000000000000000000000000000000008152600401610b1f9190613a4d565b60405180910390fd5b81600b819055505050565b60018054610b4090614193565b80601f0160208091040260200160405190810160405280929190818152602001828054610b6c90614193565b8015610bb95780601f10610b8e57610100808354040283529160200191610bb9565b820191906000526020600020905b815481529060010190602001808311610b9c57829003601f168201915b505050505081565b60036020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b80610bfe81612a50565b610c3f57806040517f1cf4d9a4000000000000000000000000000000000000000000000000000000008152600401610c369190613ae3565b60405180910390fd5b60003390506000610c4f84612a6f565b90508073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610cc157846040517ff2b21e1c000000000000000000000000000000000000000000000000000000008152600401610cb89190613a4d565b60405180910390fd5b6000610cce828487612b35565b905080610d16578183866040517f19f48dff000000000000000000000000000000000000000000000000000000008152600401610d0d939291906141c4565b60405180910390fd5b856003600087815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550848673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050505050565b6000610dd5612bee565b905090565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610faa573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610e4c57610e47848484612bfd565b610fb6565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610e959291906141fb565b602060405180830381865afa158015610eb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed69190614239565b8015610f6857506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610f269291906141fb565b602060405180830381865afa158015610f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f679190614239565b5b610fa957336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610fa09190613a4d565b60405180910390fd5b5b610fb5848484612bfd565b5b50505050565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff161461102a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611021906142b2565b60405180910390fd5b600280600381111561103f5761103e613e95565b5b601060009054906101000a900460ff16600381111561106157611060613e95565b5b146110a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110989061431e565b60405180910390fd5b6000801b600d54036110df576040517f93dff14200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000339050600f60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561117357806040517f6acdb09500000000000000000000000000000000000000000000000000000000815260040161116a9190613a4d565b60405180910390fd5b6000816040516020016111869190614386565b6040516020818303038152906040528051906020012090506000600d546111ad8684612d9d565b149050806111f257826040517f186a628d0000000000000000000000000000000000000000000000000000000081526004016111e99190613a4d565b60405180910390fd5b60006111fc610dcb565b9050600c54600a548261120f91906143d0565b1115611250576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161124790614450565b60405180910390fd5b6008543414611294576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128b906144bc565b60405180910390fd5b6112a033600a54612df3565b6001600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550505050505050565b600061130b83612fae565b82106113505782826040517f374f8b4f0000000000000000000000000000000000000000000000000000000081526004016113479291906144dc565b60405180910390fd5b600080600190505b6000548110156113e25761136b81612a50565b80156113aa575061137b81612a6f565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16145b156113cf578184036113c05780925050506113e5565b81806113cb90614505565b9250505b80806113da90614505565b915050611358565b50505b92915050565b60116020528060005260406000206000915090505481565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156115d3573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036114755761147084848461310b565b6115df565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016114be9291906141fb565b602060405180830381865afa1580156114db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ff9190614239565b801561159157506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b815260040161154f9291906141fb565b602060405180830381865afa15801561156c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115909190614239565b5b6115d257336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016115c99190613a4d565b60405180910390fd5b5b6115de84848461310b565b5b50505050565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614611653576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164a906142b2565b60405180910390fd5b600180600381111561166857611667613e95565b5b601060009054906101000a900460ff16600381111561168a57611689613e95565b5b146116ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116c19061431e565b60405180910390fd5b6000801b600d5403611708576040517f93dff14200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000339050600e60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561179c57806040517f6acdb0950000000000000000000000000000000000000000000000000000000081526004016117939190613a4d565b60405180910390fd5b6000816040516020016117af9190614386565b6040516020818303038152906040528051906020012090506000600d546117d68684612d9d565b1490508061181b57826040517f186a628d0000000000000000000000000000000000000000000000000000000081526004016118129190613a4d565b60405180910390fd5b6000611825610dcb565b9050600c54600a548261183891906143d0565b1115611879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187090614450565b60405180910390fd5b60085434146118bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b4906144bc565b60405180910390fd5b6118c933600a54612df3565b6001600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550505050505050565b6000611933611ce7565b821061197657816040517f125c19b000000000000000000000000000000000000000000000000000000000815260040161196d9190613ae3565b60405180910390fd5b60018261198391906143d0565b9050919050565b60003390508073ffffffffffffffffffffffffffffffffffffffff166119ae611cfd565b73ffffffffffffffffffffffffffffffffffffffff1614611a0657806040517f55932a1b0000000000000000000000000000000000000000000000000000000081526004016119fd9190613a4d565b60405180910390fd5b611a0f8261312b565b5050565b60003390508073ffffffffffffffffffffffffffffffffffffffff16611a37611cfd565b73ffffffffffffffffffffffffffffffffffffffff1614611a8f57806040517f55932a1b000000000000000000000000000000000000000000000000000000008152600401611a869190613a4d565b60405180910390fd5b81601060006101000a81548160ff02191690836003811115611ab457611ab3613e95565b5b02179055505050565b601060009054906101000a900460ff1681565b600081611adc81612a50565b611b1d57806040517f1cf4d9a4000000000000000000000000000000000000000000000000000000008152600401611b149190613ae3565b60405180910390fd5b611b2683612a6f565b915050919050565b600a5481565b60003390508073ffffffffffffffffffffffffffffffffffffffff16611b58611cfd565b73ffffffffffffffffffffffffffffffffffffffff1614611bb057806040517f55932a1b000000000000000000000000000000000000000000000000000000008152600401611ba79190613a4d565b60405180910390fd5b6000611bba610dcb565b9050808311611bfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf5906145bf565b60405180910390fd5b600c548310611c42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3990614651565b60405180910390fd5b82600c81905550505050565b6000611c5982612fae565b9050919050565b60003390508073ffffffffffffffffffffffffffffffffffffffff16611c84611cfd565b73ffffffffffffffffffffffffffffffffffffffff1614611cdc57806040517f55932a1b000000000000000000000000000000000000000000000000000000008152600401611cd39190613a4d565b60405180910390fd5b816008819055505050565b60006001600054611cf89190614671565b905090565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60028054611d3490614193565b80601f0160208091040260200160405190810160405280929190818152602001828054611d6090614193565b8015611dad5780601f10611d8257610100808354040283529160200191611dad565b820191906000526020600020905b815481529060010190602001808311611d9057829003601f168201915b505050505081565b60003390508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611e2a57826040517ff2b21e1c000000000000000000000000000000000000000000000000000000008152600401611e219190613a4d565b60405180910390fd5b81600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3184604051611f1b91906138dc565b60405180910390a3505050565b60095481565b8360006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156120ff573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611fa157611f9c8585858561313e565b61210c565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611fea9291906141fb565b602060405180830381865afa158015612007573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202b9190614239565b80156120bd57506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b815260040161207b9291906141fb565b602060405180830381865afa158015612098573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120bc9190614239565b5b6120fe57336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016120f59190613a4d565b60405180910390fd5b5b61210b8585858561313e565b5b5050505050565b60003390508073ffffffffffffffffffffffffffffffffffffffff16612137611cfd565b73ffffffffffffffffffffffffffffffffffffffff161461218f57806040517f55932a1b0000000000000000000000000000000000000000000000000000000081526004016121869190613a4d565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146121fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121f4906142b2565b60405180910390fd5b6000612207610dcb565b9050600c54848261221891906143d0565b1115612259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225090614450565b60405180910390fd5b6122638385612df3565b50505050565b60003390508073ffffffffffffffffffffffffffffffffffffffff1661228d611cfd565b73ffffffffffffffffffffffffffffffffffffffff16146122e557806040517f55932a1b0000000000000000000000000000000000000000000000000000000081526004016122dc9190613a4d565b60405180910390fd5b816009819055505050565b6060816122fc81612a50565b61233d57806040517f1cf4d9a40000000000000000000000000000000000000000000000000000000081526004016123349190613ae3565b60405180910390fd5b60006006805461234c90614193565b9050116123615761235c8361319c565b61238d565b600661236c8461319c565b60405160200161237d929190614779565b6040516020818303038152906040525b915050919050565b60003390508073ffffffffffffffffffffffffffffffffffffffff166123b9611cfd565b73ffffffffffffffffffffffffffffffffffffffff161461241157806040517f55932a1b0000000000000000000000000000000000000000000000000000000081526004016124089190613a4d565b60405180910390fd5b81600a819055505050565b600b5481565b600c5481565b600061243483836132fc565b905092915050565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff16146124aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124a1906142b2565b60405180910390fd5b60038060038111156124bf576124be613e95565b5b601060009054906101000a900460ff1660038111156124e1576124e0613e95565b5b14612521576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125189061431e565b60405180910390fd5b600061252b610dcb565b9050600b5483601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461257b91906143d0565b11156125bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125b3906147e9565b60405180910390fd5b600c5483826125cb91906143d0565b111561260c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161260390614450565b60405180910390fd5b6009548361261a9190614809565b341461265b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612652906144bc565b60405180910390fd5b6126653384612df3565b82601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546126b491906143d0565b92505081905550505050565b60003390508073ffffffffffffffffffffffffffffffffffffffff166126e4611cfd565b73ffffffffffffffffffffffffffffffffffffffff161461273c57806040517f55932a1b0000000000000000000000000000000000000000000000000000000081526004016127339190613a4d565b60405180910390fd5b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505050565b60003390508073ffffffffffffffffffffffffffffffffffffffff16612827611cfd565b73ffffffffffffffffffffffffffffffffffffffff161461287f57806040517f55932a1b0000000000000000000000000000000000000000000000000000000081526004016128769190613a4d565b60405180910390fd5b6000479050600081116128c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128be90614897565b60405180910390fd5b8083111561290a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161290190614903565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff168560405161293590614954565b60006040518083038185875af1925050503d8060008114612972576040519150601f19603f3d011682016040523d82523d6000602084013e612977565b606091505b50509050806129bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129b2906149b5565b60405180910390fd5b505050505050565b60003390508073ffffffffffffffffffffffffffffffffffffffff166129e7611cfd565b73ffffffffffffffffffffffffffffffffffffffff1614612a3f57806040517f55932a1b000000000000000000000000000000000000000000000000000000008152600401612a369190613a4d565b60405180910390fd5b81600d819055505050565b60085481565b6000808203612a625760009050612a6a565b600054821090505b919050565b60008082905060006005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612b2b578180612aed906149d5565b9250506005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050612aae565b8092505050919050565b6000808473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612bd057506003600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16145b80612be15750612be085856132fc565b5b9050809150509392505050565b6000612bf8611ce7565b905090565b80612c0781612a50565b612c4857806040517f1cf4d9a4000000000000000000000000000000000000000000000000000000008152600401612c3f9190613ae3565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612cae576040517f14242cb600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003390506000612cbe84612a6f565b90508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614612d34578086856040517fe02b28e7000000000000000000000000000000000000000000000000000000008152600401612d2b939291906141c4565b60405180910390fd5b6000612d41828487612b35565b905080612d89578183866040517f19f48dff000000000000000000000000000000000000000000000000000000008152600401612d80939291906141c4565b60405180910390fd5b612d94828787613390565b50505050505050565b60008082905060005b8451811015612de857612dd382868381518110612dc657612dc56149fe565b5b6020026020010151613678565b91508080612de090614505565b915050612da6565b508091505092915050565b60008054905060008282612e0791906143d0565b90506000600182612e189190614671565b9050846005600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082811115612ec757846005600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b81600081905550612eea60008685604051806020016040528060008152506136a3565b612f2b57846040517f015be56a000000000000000000000000000000000000000000000000000000008152600401612f229190613a4d565b60405180910390fd5b60008390505b82811015612fa657808673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a480612f9f90614505565b9050612f31565b505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612fec5760009050613106565b60008080600190505b6000548110156130ff5761300881612a50565b156130ee57600073ffffffffffffffffffffffffffffffffffffffff166005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146130ab576005600082815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505b8173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036130ed5782806130e990614505565b9350505b5b806130f890614505565b9050612ff5565b5081925050505b919050565b61312683838360405180602001604052806000815250611f2e565b505050565b806006908161313a9190614bc4565b5050565b613149848484610dda565b613155848484846136a3565b61319657826040517f015be56a00000000000000000000000000000000000000000000000000000000815260040161318d9190613a4d565b60405180910390fd5b50505050565b6060600082036131e3576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506132f7565b600082905060005b600082146132155780806131fe90614505565b915050600a8261320e9190614cc5565b91506131eb565b60008167ffffffffffffffff81111561323157613230613b56565b5b6040519080825280601f01601f1916602001820160405280156132635781602001600182028036833780820191505090505b5090505b600085146132f05760018261327c9190614671565b9150600a8561328b9190614cf6565b603061329791906143d0565b60f81b8183815181106132ad576132ac6149fe565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856132e99190614cc5565b9450613267565b8093505050505b919050565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60006003600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600182116133f4576001613402565b6001826134019190614671565b5b9050600060018361341391906143d0565b90506000838310801561342b575061342a83612a50565b5b80156134965750600073ffffffffffffffffffffffffffffffffffffffff166005600085815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b905060006134a383612a50565b801561350e5750600073ffffffffffffffffffffffffffffffffffffffff166005600085815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b9050811561356957866005600086815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b80156135c257866005600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b856005600087815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550848673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450505050505050565b60008183106136905761368b8284613811565b61369b565b61369a8383613811565b5b905092915050565b600080843b90506000811115613803578473ffffffffffffffffffffffffffffffffffffffff1663150b7a02338887876040518563ffffffff1660e01b81526004016136f29493929190614d7c565b6020604051808303816000875af192505050801561372e57506040513d601f19601f8201168201806040525081019061372b9190614ddd565b60015b6137b2573d806000811461375e576040519150601f19603f3d011682016040523d82523d6000602084013e613763565b606091505b5060008151036137aa57856040517f015be56a0000000000000000000000000000000000000000000000000000000081526004016137a19190613a4d565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161492505050613809565b60019150505b949350505050565b600082600052816020526040600020905092915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6138718161383c565b811461387c57600080fd5b50565b60008135905061388e81613868565b92915050565b6000602082840312156138aa576138a9613832565b5b60006138b88482850161387f565b91505092915050565b60008115159050919050565b6138d6816138c1565b82525050565b60006020820190506138f160008301846138cd565b92915050565b6000819050919050565b61390a816138f7565b811461391557600080fd5b50565b60008135905061392781613901565b92915050565b60006020828403121561394357613942613832565b5b600061395184828501613918565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613994578082015181840152602081019050613979565b60008484015250505050565b6000601f19601f8301169050919050565b60006139bc8261395a565b6139c68185613965565b93506139d6818560208601613976565b6139df816139a0565b840191505092915050565b60006020820190508181036000830152613a0481846139b1565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613a3782613a0c565b9050919050565b613a4781613a2c565b82525050565b6000602082019050613a626000830184613a3e565b92915050565b613a7181613a2c565b8114613a7c57600080fd5b50565b600081359050613a8e81613a68565b92915050565b60008060408385031215613aab57613aaa613832565b5b6000613ab985828601613a7f565b9250506020613aca85828601613918565b9150509250929050565b613add816138f7565b82525050565b6000602082019050613af86000830184613ad4565b92915050565b600080600060608486031215613b1757613b16613832565b5b6000613b2586828701613a7f565b9350506020613b3686828701613a7f565b9250506040613b4786828701613918565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613b8e826139a0565b810181811067ffffffffffffffff82111715613bad57613bac613b56565b5b80604052505050565b6000613bc0613828565b9050613bcc8282613b85565b919050565b600067ffffffffffffffff821115613bec57613beb613b56565b5b602082029050602081019050919050565b600080fd5b6000819050919050565b613c1581613c02565b8114613c2057600080fd5b50565b600081359050613c3281613c0c565b92915050565b6000613c4b613c4684613bd1565b613bb6565b90508083825260208201905060208402830185811115613c6e57613c6d613bfd565b5b835b81811015613c975780613c838882613c23565b845260208401935050602081019050613c70565b5050509392505050565b600082601f830112613cb657613cb5613b51565b5b8135613cc6848260208601613c38565b91505092915050565b600060208284031215613ce557613ce4613832565b5b600082013567ffffffffffffffff811115613d0357613d02613837565b5b613d0f84828501613ca1565b91505092915050565b600060208284031215613d2e57613d2d613832565b5b6000613d3c84828501613a7f565b91505092915050565b600080fd5b600067ffffffffffffffff821115613d6557613d64613b56565b5b613d6e826139a0565b9050602081019050919050565b82818337600083830152505050565b6000613d9d613d9884613d4a565b613bb6565b905082815260208101848484011115613db957613db8613d45565b5b613dc4848285613d7b565b509392505050565b600082601f830112613de157613de0613b51565b5b8135613df1848260208601613d8a565b91505092915050565b600060208284031215613e1057613e0f613832565b5b600082013567ffffffffffffffff811115613e2e57613e2d613837565b5b613e3a84828501613dcc565b91505092915050565b60048110613e5057600080fd5b50565b600081359050613e6281613e43565b92915050565b600060208284031215613e7e57613e7d613832565b5b6000613e8c84828501613e53565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110613ed557613ed4613e95565b5b50565b6000819050613ee682613ec4565b919050565b6000613ef682613ed8565b9050919050565b613f0681613eeb565b82525050565b6000602082019050613f216000830184613efd565b92915050565b613f30816138c1565b8114613f3b57600080fd5b50565b600081359050613f4d81613f27565b92915050565b60008060408385031215613f6a57613f69613832565b5b6000613f7885828601613a7f565b9250506020613f8985828601613f3e565b9150509250929050565b600067ffffffffffffffff821115613fae57613fad613b56565b5b613fb7826139a0565b9050602081019050919050565b6000613fd7613fd284613f93565b613bb6565b905082815260208101848484011115613ff357613ff2613d45565b5b613ffe848285613d7b565b509392505050565b600082601f83011261401b5761401a613b51565b5b813561402b848260208601613fc4565b91505092915050565b6000806000806080858703121561404e5761404d613832565b5b600061405c87828801613a7f565b945050602061406d87828801613a7f565b935050604061407e87828801613918565b925050606085013567ffffffffffffffff81111561409f5761409e613837565b5b6140ab87828801614006565b91505092959194509250565b600080604083850312156140ce576140cd613832565b5b60006140dc85828601613918565b92505060206140ed85828601613a7f565b9150509250929050565b6000806040838503121561410e5761410d613832565b5b600061411c85828601613a7f565b925050602061412d85828601613a7f565b9150509250929050565b60006020828403121561414d5761414c613832565b5b600061415b84828501613c23565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806141ab57607f821691505b6020821081036141be576141bd614164565b5b50919050565b60006060820190506141d96000830186613a3e565b6141e66020830185613a3e565b6141f36040830184613ad4565b949350505050565b60006040820190506142106000830185613a3e565b61421d6020830184613a3e565b9392505050565b60008151905061423381613f27565b92915050565b60006020828403121561424f5761424e613832565b5b600061425d84828501614224565b91505092915050565b7f4e6f20736d61727420636f6e7472616374732061726520616c6c6f7765640000600082015250565b600061429c601e83613965565b91506142a782614266565b602082019050919050565b600060208201905081810360008301526142cb8161428f565b9050919050565b7f53616c65206e6f74206163746976650000000000000000000000000000000000600082015250565b6000614308600f83613965565b9150614313826142d2565b602082019050919050565b60006020820190508181036000830152614337816142fb565b9050919050565b60008160601b9050919050565b60006143568261433e565b9050919050565b60006143688261434b565b9050919050565b61438061437b82613a2c565b61435d565b82525050565b6000614392828461436f565b60148201915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006143db826138f7565b91506143e6836138f7565b92508282019050808211156143fe576143fd6143a1565b5b92915050565b7f4578636565647320737570706c79000000000000000000000000000000000000600082015250565b600061443a600e83613965565b915061444582614404565b602082019050919050565b600060208201905081810360008301526144698161442d565b9050919050565b7f45746865722073656e74206973206e6f7420636f727265637400000000000000600082015250565b60006144a6601983613965565b91506144b182614470565b602082019050919050565b600060208201905081810360008301526144d581614499565b9050919050565b60006040820190506144f16000830185613a3e565b6144fe6020830184613ad4565b9392505050565b6000614510826138f7565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614542576145416143a1565b5b600182019050919050565b7f4d617820737570706c792073686f756c6420626520677265617465722074686160008201527f6e2063757272656e7420737570706c7900000000000000000000000000000000602082015250565b60006145a9603083613965565b91506145b48261454d565b604082019050919050565b600060208201905081810360008301526145d88161459c565b9050919050565b7f4d617820737570706c792073686f756c6420626520677265617465722074686160008201527f6e2070726576696f7573206d617820737570706c790000000000000000000000602082015250565b600061463b603583613965565b9150614646826145df565b604082019050919050565b6000602082019050818103600083015261466a8161462e565b9050919050565b600061467c826138f7565b9150614687836138f7565b925082820390508181111561469f5761469e6143a1565b5b92915050565b600081905092915050565b60008190508160005260206000209050919050565b600081546146d281614193565b6146dc81866146a5565b945060018216600081146146f7576001811461470c5761473f565b60ff198316865281151582028601935061473f565b614715856146b0565b60005b8381101561473757815481890152600182019150602081019050614718565b838801955050505b50505092915050565b60006147538261395a565b61475d81856146a5565b935061476d818560208601613976565b80840191505092915050565b600061478582856146c5565b91506147918284614748565b91508190509392505050565b7f45786365656473206d696e74207065722077616c6c6574000000000000000000600082015250565b60006147d3601783613965565b91506147de8261479d565b602082019050919050565b60006020820190508181036000830152614802816147c6565b9050919050565b6000614814826138f7565b915061481f836138f7565b925082820261482d816138f7565b91508282048414831517614844576148436143a1565b5b5092915050565b7f4e6f2062616c616e636520746f20776974686472617700000000000000000000600082015250565b6000614881601683613965565b915061488c8261484b565b602082019050919050565b600060208201905081810360008301526148b081614874565b9050919050565b7f416d6f756e74206973206e6f742076616c696400000000000000000000000000600082015250565b60006148ed601383613965565b91506148f8826148b7565b602082019050919050565b6000602082019050818103600083015261491c816148e0565b9050919050565b600081905092915050565b50565b600061493e600083614923565b91506149498261492e565b600082019050919050565b600061495f82614931565b9150819050919050565b7f5472616e73616374696f6e206661696c65640000000000000000000000000000600082015250565b600061499f601283613965565b91506149aa82614969565b602082019050919050565b600060208201905081810360008301526149ce81614992565b9050919050565b60006149e0826138f7565b9150600082036149f3576149f26143a1565b5b600182039050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020601f8301049050919050565b600082821b905092915050565b600060088302614a7a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614a3d565b614a848683614a3d565b95508019841693508086168417925050509392505050565b6000819050919050565b6000614ac1614abc614ab7846138f7565b614a9c565b6138f7565b9050919050565b6000819050919050565b614adb83614aa6565b614aef614ae782614ac8565b848454614a4a565b825550505050565b600090565b614b04614af7565b614b0f818484614ad2565b505050565b5b81811015614b3357614b28600082614afc565b600181019050614b15565b5050565b601f821115614b7857614b49816146b0565b614b5284614a2d565b81016020851015614b61578190505b614b75614b6d85614a2d565b830182614b14565b50505b505050565b600082821c905092915050565b6000614b9b60001984600802614b7d565b1980831691505092915050565b6000614bb48383614b8a565b9150826002028217905092915050565b614bcd8261395a565b67ffffffffffffffff811115614be657614be5613b56565b5b614bf08254614193565b614bfb828285614b37565b600060209050601f831160018114614c2e5760008415614c1c578287015190505b614c268582614ba8565b865550614c8e565b601f198416614c3c866146b0565b60005b82811015614c6457848901518255600182019150602085019450602081019050614c3f565b86831015614c815784890151614c7d601f891682614b8a565b8355505b6001600288020188555050505b505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614cd0826138f7565b9150614cdb836138f7565b925082614ceb57614cea614c96565b5b828204905092915050565b6000614d01826138f7565b9150614d0c836138f7565b925082614d1c57614d1b614c96565b5b828206905092915050565b600081519050919050565b600082825260208201905092915050565b6000614d4e82614d27565b614d588185614d32565b9350614d68818560208601613976565b614d71816139a0565b840191505092915050565b6000608082019050614d916000830187613a3e565b614d9e6020830186613a3e565b614dab6040830185613ad4565b8181036060830152614dbd8184614d43565b905095945050505050565b600081519050614dd781613868565b92915050565b600060208284031215614df357614df2613832565b5b6000614e0184828501614dc8565b9150509291505056fea2646970667358221220ff14bd865b00fa40770dcc60e989ad61973c8b2b0c621a86db37e1f3ba25422964736f6c63430008110033
Verified Source Code Full Match
Compiler: v0.8.17+commit.8df45f5f
EVM: london
Optimization: No
UndeadChef.sol 285 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
// Contract by @AsteriaLabs
import "./Reg_ERC721Batch.sol";
import "./utils/ERC173.sol";
import "./interfaces/DefaultOperatorFilterer.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
/// @title Undead Chef
/// @author <@Suleman132446>
contract UndeadChef is
Reg_ERC721Batch,
ERC173,
DefaultOperatorFilterer
{
using MerkleProof for bytes32[];
uint256 public whitelistPrice = 0.005 ether;
uint256 public publicPrice = 0.005 ether;
uint256 public maxPerWhitelist = 3;
uint256 public maxPerPublic = 3;
uint256 public maxSupply = 4000;
error Whitelist_NOT_SET();
error Whitelist_CONSUMED(address account);
error Whitelist_FORBIDDEN(address account);
bytes32 private _root;
mapping(address => bool) private _private_consumed;
mapping(address => bool) private _private_next;
/**
@dev An enum representing the sale state
*/
enum Sale {
PAUSED,
PRIVATE,
PRIVATE_NEXT,
PUBLIC
}
Sale public saleState = Sale.PAUSED;
// Mapping of nft minted by a wallet in public
mapping(address => uint256) public mintedPerWallet;
// Modifier to allow only owner
// Modifier to check the sale state
modifier isSaleState(Sale sale_) {
require(saleState == sale_, "Sale not active");
_;
}
// Modifier to block the other contracts
modifier blockContracts() {
require(tx.origin == msg.sender, "No smart contracts are allowed");
_;
}
constructor(
string memory name_,
string memory symbol_,
string memory baseURI_
) {
__init_ERC721Metadata(name_, symbol_, baseURI_);
_setOwner(msg.sender);
}
/**
* @dev tranfer the funds from contract
*
* @param to_ : the address of the wallet to transfer the funds
*/
function withdraw(address to_, uint amount_) public onlyOwner {
uint256 _balance_ = address(this).balance;
require(_balance_ > 0, "No balance to withdraw");
require(amount_ <= _balance_, "Amount is not valid");
address _recipient_ = payable(to_);
(bool _success_, ) = _recipient_.call{value: amount_}("");
require(_success_, "Transaction failed");
}
/**
* @dev set the whiltelist price
*
* @param price_ : the price of whitelist mint
*/
function setWhitelistPrice(uint256 price_) external onlyOwner {
whitelistPrice = price_;
}
/**
* @dev set the public mint price
*
* @param price_ : the price of public mint
*/
function setPublicPrice(uint256 price_) external onlyOwner {
publicPrice = price_;
}
/**
* @dev set the mints per wallet in whitelist
*
* @param mints_ : the amount of for whitelist mint
*/
function setMintsPerWhitelist(uint256 mints_) external onlyOwner {
maxPerWhitelist = mints_;
}
/**
* @dev set the mints per wallet in public
*
* @param mints_ : the amount of for public mint
*/
function setMintsPerPublic(uint256 mints_) external onlyOwner {
maxPerPublic = mints_;
}
/**
* @dev set the max supply for collection
*
* @param supply_ : the amount for supply
*/
function setMaxSupply(uint256 supply_) external onlyOwner {
uint _currentSupply_ = totalSupply();
require(
supply_ > _currentSupply_,
"Max supply should be greater than current supply"
);
require(
supply_ < maxSupply,
"Max supply should be greater than previous max supply"
);
maxSupply = supply_;
}
/**
* @dev set the merkle root for whitelist
*
* @param root_ : the merkle for whitelist
*/
function setWhitelistRoot(bytes32 root_) external onlyOwner {
_root = root_;
}
/**
* @dev set the base uri for collection
*
* @param baseURI_ : the base uri for collection
*/
function setBaseURI(string memory baseURI_) external onlyOwner {
_setBaseURI(baseURI_);
}
/**
* @dev set the sale state
*
* @param sale_ : the new sale state
*/
function setSaleState(Sale sale_) external onlyOwner {
saleState = sale_;
}
function mintWhitelist(bytes32[] memory proof_)
external
payable
blockContracts
isSaleState(Sale.PRIVATE)
{
if (_root == 0) {
revert Whitelist_NOT_SET();
}
address account_ = msg.sender;
if (_private_consumed[account_]) {
revert Whitelist_CONSUMED(account_);
}
bytes32 leaf = keccak256(abi.encodePacked(account_));
bool isAllowed = MerkleProof.processProof(proof_, leaf) == _root;
if (!isAllowed) {
revert Whitelist_FORBIDDEN(account_);
}
uint _supply_ = totalSupply();
require(_supply_ + maxPerWhitelist <= maxSupply, "Exceeds supply");
require(
msg.value == whitelistPrice,
"Ether sent is not correct"
);
_mint(msg.sender, maxPerWhitelist);
_private_consumed[account_] = true;
}
function mintNextWhitelist(bytes32[] memory proof_)
external
payable
blockContracts
isSaleState(Sale.PRIVATE_NEXT)
{
if (_root == 0) {
revert Whitelist_NOT_SET();
}
address account_ = msg.sender;
if (_private_next[account_]) {
revert Whitelist_CONSUMED(account_);
}
bytes32 leaf = keccak256(abi.encodePacked(account_));
bool isAllowed = MerkleProof.processProof(proof_, leaf) == _root;
if (!isAllowed) {
revert Whitelist_FORBIDDEN(account_);
}
uint _supply_ = totalSupply();
require(_supply_ + maxPerWhitelist <= maxSupply, "Exceeds supply");
require(
msg.value == whitelistPrice,
"Ether sent is not correct"
);
_mint(msg.sender, maxPerWhitelist);
_private_next[account_] = true;
}
/**
* @dev mint the token for airdrop
*
* @param qty_ : the quantity of mint
* @param to_: the address to send to
*/
function airdrop( uint256 qty_ , address to_) onlyOwner
external
payable
blockContracts
{
uint _supply_ = totalSupply();
require(_supply_ + qty_ <= maxSupply, "Exceeds supply");
_mint(to_, qty_);
}
/**
* @dev mint the token in public sale
*
* @param qty_ : the quantity of mint
*/
function mintPublic(uint256 qty_)
external
payable
blockContracts
isSaleState(Sale.PUBLIC)
{
uint _supply_ = totalSupply();
require(
mintedPerWallet[msg.sender] + qty_ <= maxPerPublic,
"Exceeds mint per wallet"
);
require(_supply_ + qty_ <= maxSupply, "Exceeds supply");
require(msg.value == qty_ * publicPrice, "Ether sent is not correct");
_mint(msg.sender, qty_);
mintedPerWallet[msg.sender] += qty_;
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public override onlyAllowedOperator(from) {
super.transferFrom(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public override onlyAllowedOperator(from) {
super.safeTransferFrom(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory data
) public override onlyAllowedOperator(from) {
super.safeTransferFrom(from, to, tokenId, data);
}
}
ERC173.sol 81 lines
// SPDX-License-Identifier: MIT
/**
* Author: Lambdalf the White
*/
pragma solidity 0.8.17;
import "../interfaces/IERC173.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract ERC173 is IERC173 {
// Errors
/**
* @dev Thrown when `operator` is not the contract owner.
*
* @param operator : address trying to use a function reserved to contract owner without authorization
*/
error IERC173_NOT_OWNER( address operator );
// The owner of the contract
address private _owner;
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
address _sender_ = msg.sender;
if ( owner() != _sender_ ) {
revert IERC173_NOT_OWNER( _sender_ );
}
_;
}
/**
* @dev Sets the contract owner.
*
* Note: This function needs to be called in the contract constructor to initialize the contract owner,
* if it is not, then parts of the contract might be non functional
*
* @param owner_ : address that owns the contract
*/
function _setOwner( address owner_ ) internal {
_owner = owner_;
}
/**
* @dev Returns the address of the current contract owner.
*
* @return address : the current contract owner
*/
function owner() public view virtual returns ( address ) {
return _owner;
}
/**
* @dev Transfers ownership of the contract to `newOwner_`.
*
* @param newOwner_ : address of the new contract owner
*
* Requirements:
*
* - Caller must be the contract owner.
*/
function transferOwnership( address newOwner_ ) public virtual onlyOwner {
address _oldOwner_ = _owner;
_owner = newOwner_;
emit OwnershipTransferred( _oldOwner_, newOwner_ );
}
}
Reg_ERC721Batch.sol 613 lines
// SPDX-License-Identifier: MIT
/**
* Author: Lambdalf the White
*/
pragma solidity 0.8.17;
import "./interfaces/IERC721Errors.sol";
import "./interfaces/IERC165.sol";
import "./interfaces/IERC721.sol";
import "./interfaces/IERC721Enumerable.sol";
import "./interfaces/IERC721Metadata.sol";
import "./interfaces/IERC721Receiver.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
* This contract features:
* ~ Very Cheap batch minting
* ~ Token tracker support
*
* Note: This implementation imposes a very expensive `balanceOf()` and `ownerOf()`.
* It is not recommended to interract with those from another contract.
*/
abstract contract Reg_ERC721Batch is
IERC721Errors,
IERC165,
IERC721,
IERC721Metadata,
IERC721Enumerable
{
uint256 private _nextId = 1;
string public name;
string public symbol;
// Mapping from token ID to approved address
mapping(uint256 => address) public getApproved;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
// List of owner addresses
mapping(uint256 => address) private _owners;
// Token Base URI
string private _baseURI;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
function __init_ERC721Metadata(
string memory name_,
string memory symbol_,
string memory baseURI_
) internal {
name = name_;
symbol = symbol_;
_baseURI = baseURI_;
}
// **************************************
// ***** MODIFIER *****
// **************************************
/**
* @dev Ensures the token exist.
* A token exists if it has been minted and is not owned by the null address.
*
* @param tokenId_ : identifier of the NFT being referenced
*/
modifier exists(uint256 tokenId_) {
if (!_exists(tokenId_)) {
revert IERC721_NONEXISTANT_TOKEN(tokenId_);
}
_;
}
// **************************************
// **************************************
// ***** INTERNAL *****
// **************************************
/**
* @dev Internal function returning the number of tokens in `tokenOwner_`'s account.
*/
function _balanceOf(address tokenOwner_)
internal
view
virtual
returns (uint256)
{
if (tokenOwner_ == address(0)) {
return 0;
}
uint256 _count_ = 0;
address _currentTokenOwner_;
for (uint256 i = 1; i < _nextId; ++i) {
if (_exists(i)) {
if (_owners[i] != address(0)) {
_currentTokenOwner_ = _owners[i];
}
if (tokenOwner_ == _currentTokenOwner_) {
_count_++;
}
}
}
return _count_;
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from_ address representing the previous owner of the given token ID
* @param to_ target address that will receive the tokens
* @param tokenId_ uint256 ID of the token to be transferred
* @param data_ bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(
address from_,
address to_,
uint256 tokenId_,
bytes memory data_
) internal virtual returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
//
// IMPORTANT
// It is unsafe to assume that an address not flagged by this method
// is an externally-owned account (EOA) and not a contract.
//
// Among others, the following types of addresses will not be flagged:
//
// - an externally-owned account
// - a contract in construction
// - an address where a contract will be created
// - an address where a contract lived, but was destroyed
uint256 _size_;
assembly {
_size_ := extcodesize(to_)
}
// If address is a contract, check that it is aware of how to handle ERC721 tokens
if (_size_ > 0) {
try
IERC721Receiver(to_).onERC721Received(
msg.sender,
from_,
tokenId_,
data_
)
returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert IERC721_NON_ERC721_RECEIVER(to_);
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Internal function returning whether a token exists.
* A token exists if it has been minted and is not owned by the null address.
*
* @param tokenId_ uint256 ID of the token to verify
*
* @return bool whether the token exists
*/
function _exists(uint256 tokenId_) internal view virtual returns (bool) {
if (tokenId_ == 0) {
return false;
}
return tokenId_ < _nextId;
}
/**
* @dev Internal function returning whether `operator_` is allowed
* to manage tokens on behalf of `tokenOwner_`.
*
* @param tokenOwner_ address that owns tokens
* @param operator_ address that tries to manage tokens
*
* @return bool whether `operator_` is allowed to handle the token
*/
function _isApprovedForAll(address tokenOwner_, address operator_)
internal
view
virtual
returns (bool)
{
return _operatorApprovals[tokenOwner_][operator_];
}
/**
* @dev Internal function returning whether `operator_` is allowed to handle `tokenId_`
*
* Note: To avoid multiple checks for the same data, it is assumed that existence of `tokeId_`
* has been verified prior via {_exists}
* If it hasn't been verified, this function might panic
*
* @param operator_ address that tries to handle the token
* @param tokenId_ uint256 ID of the token to be handled
*
* @return bool whether `operator_` is allowed to handle the token
*/
function _isApprovedOrOwner(
address tokenOwner_,
address operator_,
uint256 tokenId_
) internal view virtual returns (bool) {
bool _isApproved_ = operator_ == tokenOwner_ ||
operator_ == getApproved[tokenId_] ||
_isApprovedForAll(tokenOwner_, operator_);
return _isApproved_;
}
/**
* @dev Mints `qty_` tokens and transfers them to `to_`.
*
* This internal function can be used to perform token minting.
*
* Emits one or more {Transfer} event.
*/
function _mint(address to_, uint256 qty_) internal virtual {
uint256 _firstToken_ = _nextId;
uint256 _nextStart_ = _firstToken_ + qty_;
uint256 _lastToken_ = _nextStart_ - 1;
_owners[_firstToken_] = to_;
if (_lastToken_ > _firstToken_) {
_owners[_lastToken_] = to_;
}
_nextId = _nextStart_;
if (!_checkOnERC721Received(address(0), to_, _firstToken_, "")) {
revert IERC721_NON_ERC721_RECEIVER(to_);
}
for (uint256 i = _firstToken_; i < _nextStart_; ++i) {
emit Transfer(address(0), to_, i);
}
}
/**
* @dev Internal function returning the owner of the `tokenId_` token.
*
* @param tokenId_ uint256 ID of the token to verify
*
* @return address the address of the token owner
*/
function _ownerOf(uint256 tokenId_)
internal
view
virtual
returns (address)
{
uint256 _tokenId_ = tokenId_;
address _tokenOwner_ = _owners[_tokenId_];
while (_tokenOwner_ == address(0)) {
_tokenId_--;
_tokenOwner_ = _owners[_tokenId_];
}
return _tokenOwner_;
}
/**
* @dev Internal function used to set the base URI of the collection.
*/
function _setBaseURI(string memory baseURI_) internal virtual {
_baseURI = baseURI_;
}
/**
* @dev Internal function returning the total supply.
*/
function _totalSupply() internal view virtual returns (uint256) {
return supplyMinted();
}
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function _toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Transfers `tokenId_` from `from_` to `to_`.
*
* This internal function can be used to implement alternative mechanisms to perform
* token transfer, such as signature-based, or token burning.
*
* Emits a {Transfer} event.
*/
function _transfer(
address from_,
address to_,
uint256 tokenId_
) internal virtual {
getApproved[tokenId_] = address(0);
uint256 _previousId_ = tokenId_ > 1 ? tokenId_ - 1 : 1;
uint256 _nextId_ = tokenId_ + 1;
bool _previousShouldUpdate_ = _previousId_ < tokenId_ &&
_exists(_previousId_) &&
_owners[_previousId_] == address(0);
bool _nextShouldUpdate_ = _exists(_nextId_) &&
_owners[_nextId_] == address(0);
if (_previousShouldUpdate_) {
_owners[_previousId_] = from_;
}
if (_nextShouldUpdate_) {
_owners[_nextId_] = from_;
}
_owners[tokenId_] = to_;
emit Transfer(from_, to_, tokenId_);
}
// **************************************
// **************************************
// ***** PUBLIC *****
// **************************************
/**
* @dev See {IERC721-approve}.
*/
function approve(address to_, uint256 tokenId_)
public
virtual
exists(tokenId_)
{
address _operator_ = msg.sender;
address _tokenOwner_ = _ownerOf(tokenId_);
if (to_ == _tokenOwner_) {
revert IERC721_INVALID_APPROVAL(to_);
}
bool _isApproved_ = _isApprovedOrOwner(
_tokenOwner_,
_operator_,
tokenId_
);
if (!_isApproved_) {
revert IERC721_CALLER_NOT_APPROVED(
_tokenOwner_,
_operator_,
tokenId_
);
}
getApproved[tokenId_] = to_;
emit Approval(_tokenOwner_, to_, tokenId_);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*
* Note: We can ignore `from_` as we can compare everything to the actual token owner,
* but we cannot remove this parameter to stay in conformity with IERC721
*/
function safeTransferFrom(
address from_,
address to_,
uint256 tokenId_
) public virtual override {
safeTransferFrom(from_, to_, tokenId_, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*
* Note: We can ignore `from_` as we can compare everything to the actual token owner,
* but we cannot remove this parameter to stay in conformity with IERC721
*/
function safeTransferFrom(
address from_,
address to_,
uint256 tokenId_,
bytes memory data_
) public virtual override {
transferFrom(from_, to_, tokenId_);
if (!_checkOnERC721Received(from_, to_, tokenId_, data_)) {
revert IERC721_NON_ERC721_RECEIVER(to_);
}
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator_, bool approved_)
public
virtual
override
{
address _account_ = msg.sender;
if (operator_ == _account_) {
revert IERC721_INVALID_APPROVAL(operator_);
}
_operatorApprovals[_account_][operator_] = approved_;
emit ApprovalForAll(_account_, operator_, approved_);
}
/**
* @dev See {IERC721-transferFrom}.
*
* Note: We can ignore `from_` as we can compare everything to the actual token owner,
* but we cannot remove this parameter to stay in conformity with IERC721
*/
function transferFrom(
address from_,
address to_,
uint256 tokenId_
) public virtual exists(tokenId_) {
if (to_ == address(0)) {
revert IERC721_INVALID_TRANSFER();
}
address _operator_ = msg.sender;
address _tokenOwner_ = _ownerOf(tokenId_);
if (from_ != _tokenOwner_) {
revert IERC721_INVALID_TRANSFER_FROM(_tokenOwner_, from_, tokenId_);
}
bool _isApproved_ = _isApprovedOrOwner(
_tokenOwner_,
_operator_,
tokenId_
);
if (!_isApproved_) {
revert IERC721_CALLER_NOT_APPROVED(
_tokenOwner_,
_operator_,
tokenId_
);
}
_transfer(_tokenOwner_, to_, tokenId_);
}
// **************************************
// **************************************
// ***** VIEW *****
// **************************************
/**
* @dev Returns the number of tokens in `tokenOwner_`'s account.
*/
function balanceOf(address tokenOwner_)
public
view
virtual
returns (uint256)
{
return _balanceOf(tokenOwner_);
}
/**
* @dev Returns if the `operator_` is allowed to manage all of the assets of `tokenOwner_`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address tokenOwner_, address operator_)
public
view
virtual
returns (bool)
{
return _isApprovedForAll(tokenOwner_, operator_);
}
/**
* @dev Returns the owner of the `tokenId_` token.
*
* Requirements:
*
* - `tokenId_` must exist.
*/
function ownerOf(uint256 tokenId_)
public
view
virtual
exists(tokenId_)
returns (address)
{
return _ownerOf(tokenId_);
}
/**
* @dev Returns the total number of tokens minted
*
* @return uint256 the number of tokens that have been minted so far
*/
function supplyMinted() public view virtual returns (uint256) {
return _nextId - 1;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId_)
public
view
virtual
override
returns (bool)
{
return
interfaceId_ == type(IERC721Enumerable).interfaceId ||
interfaceId_ == type(IERC721Metadata).interfaceId ||
interfaceId_ == type(IERC721).interfaceId ||
interfaceId_ == type(IERC165).interfaceId;
}
/**
* @dev See {IERC721Enumerable-tokenByIndex}.
*/
function tokenByIndex(uint256 index_)
public
view
virtual
override
returns (uint256)
{
if (index_ >= supplyMinted()) {
revert IERC721Enumerable_INDEX_OUT_OF_BOUNDS(index_);
}
return index_ + 1;
}
/**
* @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
*/
function tokenOfOwnerByIndex(address tokenOwner_, uint256 index_)
public
view
virtual
override
returns (uint256 tokenId)
{
if (index_ >= _balanceOf(tokenOwner_)) {
revert IERC721Enumerable_OWNER_INDEX_OUT_OF_BOUNDS(
tokenOwner_,
index_
);
}
uint256 _count_ = 0;
for (uint256 i = 1; i < _nextId; i++) {
if (_exists(i) && tokenOwner_ == _ownerOf(i)) {
if (index_ == _count_) {
return i;
}
_count_++;
}
}
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId_)
public
view
virtual
override
exists(tokenId_)
returns (string memory)
{
return
bytes(_baseURI).length > 0
? string(abi.encodePacked(_baseURI, _toString(tokenId_)))
: _toString(tokenId_);
}
/**
* @dev See {IERC721Enumerable-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply();
}
// **************************************
}
IERC165.sol 13 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
interface IERC165 {
/// @notice Query if a contract implements an interface
/// @param interfaceID The interface identifier, as specified in ERC-165
/// @dev Interface identification is specified in ERC-165. This function
/// uses less than 30,000 gas.
/// @return `true` if the contract implements `interfaceID` and
/// `interfaceID` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
IERC173.sol 21 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
/**
* @dev Required interface of an ERC173 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-173[EIP].
*/
interface IERC173 /* is IERC165 */ {
/// @dev This emits when ownership of a contract changes.
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/// @notice Get the address of the owner
/// @return The address of the owner.
function owner() view external returns(address);
/// @notice Set the address of the new owner of the contract
/// @dev Set _newOwner to address(0) to renounce any ownership.
/// @param _newOwner The address of the new owner of the contract
function transferOwnership(address _newOwner) external;
}
IERC721.sol 102 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)
pragma solidity 0.8.17;
/// @title ERC-721 Non-Fungible Token Standard
/// @dev See https://eips.ethereum.org/EIPS/eip-721
/// Note: the ERC-165 identifier for this interface is 0x80ac58cd.
interface IERC721 /* is IERC165 */ {
/// @dev This emits when ownership of any NFT changes by any mechanism.
/// This event emits when NFTs are created (`from` == 0) and destroyed
/// (`to` == 0). Exception: during contract creation, any number of NFTs
/// may be created and assigned without emitting Transfer. At the time of
/// any transfer, the approved address for that NFT (if any) is reset to none.
event Transfer( address indexed from_, address indexed to_, uint256 indexed tokenId_ );
/// @dev This emits when the approved address for an NFT is changed or
/// reaffirmed. The zero address indicates there is no approved address.
/// When a Transfer event emits, this also indicates that the approved
/// address for that NFT (if any) is reset to none.
event Approval( address indexed owner_, address indexed approved_, uint256 indexed tokenId_ );
/// @dev This emits when an operator is enabled or disabled for an owner.
/// The operator can manage all NFTs of the owner.
event ApprovalForAll( address indexed owner_, address indexed operator_, bool approved_ );
/// @notice Count all NFTs assigned to an owner
/// @dev NFTs assigned to the zero address are considered invalid, and this
/// function throws for queries about the zero address.
/// @param owner_ An address for whom to query the balance
/// @return The number of NFTs owned by `owner_`, possibly zero
function balanceOf( address owner_ ) external view returns ( uint256 );
/// @notice Find the owner of an NFT
/// @dev NFTs assigned to zero address are considered invalid, and queries
/// about them do throw.
/// @param tokenId_ The identifier for an NFT
/// @return The address of the owner of the NFT
function ownerOf( uint256 tokenId_ ) external view returns ( address );
/// @notice Transfers the ownership of an NFT from one address to another address
/// @dev Throws unless `msg.sender` is the current owner, an authorized
/// operator, or the approved address for this NFT. Throws if `from_` is
/// not the current owner. Throws if `to_` is the zero address. Throws if
/// `tokenId_` is not a valid NFT. When transfer is complete, this function
/// checks if `to_` is a smart contract (code size > 0). If so, it calls
/// `onERC721Received` on `to_` and throws if the return value is not
/// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
/// @param from_ The current owner of the NFT
/// @param to_ The new owner
/// @param tokenId_ The NFT to transfer
/// @param data_ Additional data with no specified format, sent in call to `to_`
function safeTransferFrom( address from_, address to_, uint256 tokenId_, bytes calldata data_ ) external;
/// @notice Transfers the ownership of an NFT from one address to another address
/// @dev This works identically to the other function with an extra data parameter,
/// except this function just sets data to "".
/// @param from_ The current owner of the NFT
/// @param to_ The new owner
/// @param tokenId_ The NFT to transfer
function safeTransferFrom( address from_, address to_, uint256 tokenId_ ) external;
/// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
/// TO CONFIRM THAT `to_` IS CAPABLE OF RECEIVING NFTS OR ELSE
/// THEY MAY BE PERMANENTLY LOST
/// @dev Throws unless `msg.sender` is the current owner, an authorized
/// operator, or the approved address for this NFT. Throws if `from_` is
/// not the current owner. Throws if `to_` is the zero address. Throws if
/// `tokenId_` is not a valid NFT.
/// @param from_ The current owner of the NFT
/// @param to_ The new owner
/// @param tokenId_ The NFT to transfer
function transferFrom( address from_, address to_, uint256 tokenId_ ) external;
/// @notice Change or reaffirm the approved address for an NFT
/// @dev The zero address indicates there is no approved address.
/// Throws unless `msg.sender` is the current NFT owner, or an authorized
/// operator of the current owner.
/// @param approved_ The new approved NFT controller
/// @param tokenId_ The NFT to approve
function approve( address approved_, uint256 tokenId_ ) external;
/// @notice Enable or disable approval for a third party ("operator") to manage
/// all of `msg.sender`'s assets
/// @dev Emits the ApprovalForAll event. The contract MUST allow
/// multiple operators per owner.
/// @param operator_ Address to add to the set of authorized operators
/// @param approved_ True if the operator is approved, false to revoke approval
function setApprovalForAll( address operator_, bool approved_ ) external;
/// @notice Get the approved address for a single NFT
/// @dev Throws if `tokenId_` is not a valid NFT.
/// @param tokenId_ The NFT to find the approved address for
/// @return The approved address for this NFT, or the zero address if there is none
function getApproved( uint256 tokenId_ ) external view returns ( address );
/// @notice Query if an address is an authorized operator for another address
/// @param owner_ The address that owns the NFTs
/// @param operator_ The address that acts on behalf of the owner
/// @return True if `operator_` is an approved operator for `owner_`, false otherwise
function isApprovedForAll( address owner_, address operator_ ) external view returns ( bool );
}
IERC721Errors.sol 61 lines
// SPDX-License-Identifier: MIT
/**
* Author: Lambdalf the White
*/
pragma solidity 0.8.17;
interface IERC721Errors {
/**
* @dev Thrown when `operator` has not been approved to manage `tokenId` on behalf of `tokenOwner`.
*
* @param tokenOwner : address owning the token
* @param operator : address trying to manage the token
* @param tokenId : identifier of the NFT being referenced
*/
error IERC721_CALLER_NOT_APPROVED( address tokenOwner, address operator, uint256 tokenId );
/**
* @dev Thrown when `operator` tries to approve themselves for managing a token they own.
*
* @param operator : address that is trying to approve themselves
*/
error IERC721_INVALID_APPROVAL( address operator );
/**
* @dev Thrown when a token is being transferred to the zero address.
*/
error IERC721_INVALID_TRANSFER();
/**
* @dev Thrown when a token is being transferred from an address that doesn't own it.
*
* @param tokenOwner : address owning the token
* @param from : address that the NFT is being transferred from
* @param tokenId : identifier of the NFT being referenced
*/
error IERC721_INVALID_TRANSFER_FROM( address tokenOwner, address from, uint256 tokenId );
/**
* @dev Thrown when the requested token doesn't exist.
*
* @param tokenId : identifier of the NFT being referenced
*/
error IERC721_NONEXISTANT_TOKEN( uint256 tokenId );
/**
* @dev Thrown when a token is being safely transferred to a contract unable to handle it.
*
* @param receiver : address unable to receive the token
*/
error IERC721_NON_ERC721_RECEIVER( address receiver );
/**
* @dev Thrown when trying to get the token at an index that doesn't exist.
*
* @param index : the inexistant index
*/
error IERC721Enumerable_INDEX_OUT_OF_BOUNDS( uint256 index );
/**
* @dev Thrown when trying to get the token owned by `tokenOwner` at an index that doesn't exist.
*
* @param tokenOwner : address owning the token
* @param index : the inexistant index
*/
error IERC721Enumerable_OWNER_INDEX_OUT_OF_BOUNDS( address tokenOwner, uint256 index );
}
IERC721Metadata.sol 20 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
/// Note: the ERC-165 identifier for this interface is 0x5b5e139f.
interface IERC721Metadata /* is IERC721 */ {
/// @notice A descriptive name for a collection of NFTs in this contract
function name() external view returns ( string memory _name );
/// @notice An abbreviated name for NFTs in this contract
function symbol() external view returns ( string memory _symbol );
/// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
/// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
/// 3986. The URI may point to a JSON file that conforms to the "ERC721
/// Metadata JSON Schema".
function tokenURI( uint256 _tokenId ) external view returns ( string memory );
}
IERC721Receiver.sol 20 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02.
interface IERC721Receiver {
/// @notice Handle the receipt of an NFT
/// @dev The ERC721 smart contract calls this function on the recipient
/// after a `transfer`. This function MAY throw to revert and reject the
/// transfer. Return of other than the magic value MUST result in the
/// transaction being reverted.
/// Note: the contract address is always the message sender.
/// @param operator_ The address which called `safeTransferFrom` function
/// @param from_ The address which previously owned the token
/// @param tokenId_ The NFT identifier which is being transferred
/// @param data_ Additional data with no specified format
/// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
/// unless throwing
function onERC721Received( address operator_, address from_, uint256 tokenId_, bytes calldata data_ ) external returns( bytes4 );
}
OperatorFilterer.sol 60 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";
abstract contract OperatorFilterer {
error OperatorNotAllowed(address operator);
IOperatorFilterRegistry constant operatorFilterRegistry =
IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);
constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
// If an inheriting token contract is deployed to a network without the registry deployed, the modifier
// will not revert, but the contract will need to be registered with the registry once it is deployed in
// order for the modifier to filter addresses.
if (address(operatorFilterRegistry).code.length > 0) {
if (subscribe) {
operatorFilterRegistry.registerAndSubscribe(
address(this),
subscriptionOrRegistrantToCopy
);
} else {
if (subscriptionOrRegistrantToCopy != address(0)) {
operatorFilterRegistry.registerAndCopyEntries(
address(this),
subscriptionOrRegistrantToCopy
);
} else {
operatorFilterRegistry.register(address(this));
}
}
}
}
modifier onlyAllowedOperator(address from) virtual {
// Check registry code length to facilitate testing in environments without a deployed registry.
if (address(operatorFilterRegistry).code.length > 0) {
// Allow spending tokens from addresses with balance
// Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
// from an EOA.
if (from == msg.sender) {
_;
return;
}
if (
!(operatorFilterRegistry.isOperatorAllowed(
address(this),
msg.sender
) &&
operatorFilterRegistry.isOperatorAllowed(
address(this),
from
))
) {
revert OperatorNotAllowed(msg.sender);
}
}
_;
}
}
IERC721Enumerable.sol 29 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
/// Note: the ERC-165 identifier for this interface is 0x780e9d63.
interface IERC721Enumerable /* is IERC721 */ {
/// @notice Count NFTs tracked by this contract
/// @return A count of valid NFTs tracked by this contract, where each one of
/// them has an assigned and queryable owner not equal to the zero address
function totalSupply() external view returns ( uint256 );
/// @notice Enumerate valid NFTs
/// @dev Throws if `index_` >= `totalSupply()`.
/// @param index_ A counter less than `totalSupply()`
/// @return The token identifier for the `index_`th NFT,
/// (sort order not specified)
function tokenByIndex( uint256 index_ ) external view returns ( uint256 );
/// @notice Enumerate NFTs assigned to an owner
/// @dev Throws if `index_` >= `balanceOf(owner_)` or if
/// `owner_` is the zero address, representing invalid NFTs.
/// @param owner_ An address where we are interested in NFTs owned by them
/// @param index_ A counter less than `balanceOf(owner_)`
/// @return The token identifier for the `index_`th NFT assigned to `owner_`,
/// (sort order not specified)
function tokenOfOwnerByIndex( address owner_, uint256 index_ ) external view returns ( uint256 );
}
DefaultOperatorFilterer.sol 10 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import {OperatorFilterer} from "./OperatorFilterer.sol";
abstract contract DefaultOperatorFilterer is OperatorFilterer {
address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);
constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}
IOperatorFilterRegistry.sol 93 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
interface IOperatorFilterRegistry {
function isOperatorAllowed(address registrant, address operator)
external
view
returns (bool);
function register(address registrant) external;
function registerAndSubscribe(address registrant, address subscription)
external;
function registerAndCopyEntries(
address registrant,
address registrantToCopy
) external;
function updateOperator(
address registrant,
address operator,
bool filtered
) external;
function updateOperators(
address registrant,
address[] calldata operators,
bool filtered
) external;
function updateCodeHash(
address registrant,
bytes32 codehash,
bool filtered
) external;
function updateCodeHashes(
address registrant,
bytes32[] calldata codeHashes,
bool filtered
) external;
function subscribe(address registrant, address registrantToSubscribe)
external;
function unsubscribe(address registrant, bool copyExistingEntries) external;
function subscriptionOf(address addr) external returns (address registrant);
function subscribers(address registrant)
external
returns (address[] memory);
function subscriberAt(address registrant, uint256 index)
external
returns (address);
function copyEntriesOf(address registrant, address registrantToCopy)
external;
function isOperatorFiltered(address registrant, address operator)
external
returns (bool);
function isCodeHashOfFiltered(address registrant, address operatorWithCode)
external
returns (bool);
function isCodeHashFiltered(address registrant, bytes32 codeHash)
external
returns (bool);
function filteredOperators(address addr)
external
returns (address[] memory);
function filteredCodeHashes(address addr)
external
returns (bytes32[] memory);
function filteredOperatorAt(address registrant, uint256 index)
external
returns (address);
function filteredCodeHashAt(address registrant, uint256 index)
external
returns (bytes32);
function isRegistered(address addr) external returns (bool);
function codeHashOf(address addr) external returns (bytes32);
}
MerkleProof.sol 227 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.2) (utils/cryptography/MerkleProof.sol)
pragma solidity ^0.8.0;
/**
* @dev These functions deal with verification of Merkle Tree proofs.
*
* The tree and the proofs can be generated using our
* https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
* You will find a quickstart guide in the readme.
*
* WARNING: You should avoid using leaf values that are 64 bytes long prior to
* hashing, or use a hash function other than keccak256 for hashing leaves.
* This is because the concatenation of a sorted pair of internal nodes in
* the merkle tree could be reinterpreted as a leaf value.
* OpenZeppelin's JavaScript library generates merkle trees that are safe
* against this attack out of the box.
*/
library MerkleProof {
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*/
function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
/**
* @dev Calldata version of {verify}
*
* _Available since v4.7._
*/
function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
return processProofCalldata(proof, leaf) == root;
}
/**
* @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
* from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
* hash matches the root of the tree. When processing the proof, the pairs
* of leafs & pre-images are assumed to be sorted.
*
* _Available since v4.4._
*/
function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Calldata version of {processProof}
*
* _Available since v4.7._
*/
function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
* `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
*
* CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
*
* _Available since v4.7._
*/
function multiProofVerify(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProof(proof, proofFlags, leaves) == root;
}
/**
* @dev Calldata version of {multiProofVerify}
*
* CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
*
* _Available since v4.7._
*/
function multiProofVerifyCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProofCalldata(proof, proofFlags, leaves) == root;
}
/**
* @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
* proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
* leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
* respectively.
*
* CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
* is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
* tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
*
* _Available since v4.7._
*/
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
// the merkle tree.
uint256 leavesLen = leaves.length;
uint256 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
// Check proof validity.
require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof");
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
// `proof` array.
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
require(proofPos == proofLen, "MerkleProof: invalid multiproof");
unchecked {
return hashes[totalHashes - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
/**
* @dev Calldata version of {processMultiProof}.
*
* CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
*
* _Available since v4.7._
*/
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
// the merkle tree.
uint256 leavesLen = leaves.length;
uint256 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
// Check proof validity.
require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof");
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
// `proof` array.
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
require(proofPos == proofLen, "MerkleProof: invalid multiproof");
unchecked {
return hashes[totalHashes - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
}
function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}
Read Contract
balanceOf 0x70a08231 → uint256
getApproved 0x081812fc → address
isApprovedForAll 0xe985e9c5 → bool
maxPerPublic 0xcfe1908d → uint256
maxPerWhitelist 0x66cc5f0d → uint256
maxSupply 0xd5abeb01 → uint256
mintedPerWallet 0x3a602b4d → uint256
name 0x06fdde03 → string
owner 0x8da5cb5b → address
ownerOf 0x6352211e → address
publicPrice 0xa945bf80 → uint256
saleState 0x603f4d52 → uint8
supplyMinted 0x7e9845f5 → uint256
supportsInterface 0x01ffc9a7 → bool
symbol 0x95d89b41 → string
tokenByIndex 0x4f6ccce7 → uint256
tokenOfOwnerByIndex 0x2f745c59 → uint256
tokenURI 0xc87b56dd → string
totalSupply 0x18160ddd → uint256
whitelistPrice 0xfc1a1c36 → uint256
Write Contract 19 functions
These functions modify contract state and require a wallet transaction to execute.
airdrop 0xbc63f02e
uint256 qty_
address to_
approve 0x095ea7b3
address to_
uint256 tokenId_
mintNextWhitelist 0x28bb1a2e
bytes32[] proof_
mintPublic 0xefd0cbf9
uint256 qty_
mintWhitelist 0x44d84381
bytes32[] proof_
safeTransferFrom 0x42842e0e
address from
address to
uint256 tokenId
safeTransferFrom 0xb88d4fde
address from
address to
uint256 tokenId
bytes data
setApprovalForAll 0xa22cb465
address operator_
bool approved_
setBaseURI 0x55f804b3
string baseURI_
setMaxSupply 0x6f8b44b0
uint256 supply_
setMintsPerPublic 0x02c366bc
uint256 mints_
setMintsPerWhitelist 0xc95d83c6
uint256 mints_
setPublicPrice 0xc6275255
uint256 price_
setSaleState 0x5a67de07
uint8 sale_
setWhitelistPrice 0x717d57d3
uint256 price_
setWhitelistRoot 0xf5aa406d
bytes32 root_
transferFrom 0x23b872dd
address from
address to
uint256 tokenId
transferOwnership 0xf2fde38b
address newOwner_
withdraw 0xf3fef3a3
address to_
uint256 amount_
Recent Transactions
No transactions found for this address