Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x8d33303023723dE93b213da4EB53bE890e747C63
ENS Name accessories.mooncatcommunity.eth
Balance 0 ETH
Nonce 1
Code Size 22121 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

22121 bytes
0x6080604052600436106102ae5760003560e01c80638789b8da11610175578063b805f331116100dc578063e771859411610095578063f2fde38b1161006f578063f2fde38b14610869578063f8d0070a14610889578063f9585a65146108a9578063fc24100b146108db576102ae565b8063e771859414610807578063edfc47c81461081c578063f09e82e214610849576102ae565b8063b805f33114610754578063d5f6247614610774578063d7fbee3d14610794578063dd9eab0d146107b4578063e3776a69146107d4578063e6c2cae6146107f4576102ae565b80639cc7f7081161012e5780639cc7f70814610694578063a36139d2146106b4578063a38097ea146106d4578063a477a7d3146106f4578063a84ec3c614610714578063aedd83fa14610734576102ae565b80638789b8da146105b85780638d766718146105d85780638da5cb5b146105f85780638e4aee061461061a5780639beab624146106475780639c798a7d14610667576102ae565b806353855967116102195780636a28f000116101d25780636a28f0001461050357806370a0823114610518578063713494d714610538578063721669d2146105585780637da9410814610578578063851caa6714610598576102ae565b8063538559671461045b5780635c4719951461047b578063624d0fe21461049b57806362a5af3b146104ae578063695f052b146104c357806369fe0e2d146104e3576102ae565b80632940bc7a1161026b5780632940bc7a1461037f57806330862bae1461039f5780633b0a6b7d146103bf57806347ef2b36146103ee5780634ebd2b771461040e57806350c6d55f1461043b576102ae565b8063054f7d9c146102b357806308b8825b146102de5780630b7dd23a146102f35780630cbc9527146103285780630ce06b681461034a578063180b0d7e1461036a575b600080fd5b3480156102bf57600080fd5b506102c86108ee565b6040516102d59190614f14565b60405180910390f35b6102f16102ec366004614810565b6108fe565b005b3480156102ff57600080fd5b5061031361030e3660046149e6565b6109b8565b6040516102d599989796959493929190615342565b34801561033457600080fd5b5061033d610cae565b6040516102d591906153fe565b34801561035657600080fd5b506102f16103653660046147a6565b610cb4565b34801561037657600080fd5b5061033d610d48565b34801561038b57600080fd5b506102f161039a366004614b8e565b610d4e565b3480156103ab57600080fd5b506102f16103ba366004614bb2565b610eb5565b3480156103cb57600080fd5b506103df6103da366004614c2d565b611091565b6040516102d5939291906153d6565b3480156103fa57600080fd5b506102f1610409366004614c2d565b6110df565b34801561041a57600080fd5b5061042e6104293660046149e6565b61120f565b6040516102d591906154a4565b34801561044757600080fd5b506102f1610456366004614b32565b61132c565b34801561046757600080fd5b5061033d610476366004614c4e565b611475565b34801561048757600080fd5b506102f16104963660046145ee565b6118b4565b61033d6104a9366004614c93565b6119db565b3480156104ba57600080fd5b506102f1611a2b565b3480156104cf57600080fd5b5061033d6104de36600461490c565b611a94565b3480156104ef57600080fd5b506102f16104fe3660046149e6565b611aec565b34801561050f57600080fd5b506102f1611b1b565b34801561052457600080fd5b5061033d6105333660046145ee565b611b54565b34801561054457600080fd5b506102f16105533660046149e6565b611b7d565b34801561056457600080fd5b506102f16105733660046149e6565b611bac565b34801561058457600080fd5b506102f1610593366004614d29565b611c58565b3480156105a457600080fd5b506102f16105b33660046147d1565b611d2c565b3480156105c457600080fd5b506102c86105d3366004614a40565b611da9565b3480156105e457600080fd5b506102f16105f3366004614d29565b611de1565b34801561060457600080fd5b5061060d611eb1565b6040516102d59190614db6565b34801561062657600080fd5b5061063a610635366004614c2d565b611ec0565b6040516102d59190615311565b34801561065357600080fd5b506102f1610662366004614c4e565b611f74565b34801561067357600080fd5b50610687610682366004614c2d565b612403565b6040516102d59190614f34565b3480156106a057600080fd5b5061033d6106af3660046149e6565b612477565b3480156106c057600080fd5b506102c86106cf3660046149e6565b612489565b3480156106e057600080fd5b506102c86106ef366004614c2d565b61249e565b34801561070057600080fd5b506102f161070f366004614b61565b6124be565b34801561072057600080fd5b5061033d61072f3660046146de565b612586565b34801561074057600080fd5b5061033d61074f3660046147a6565b6125c6565b34801561076057600080fd5b5061033d61076f366004614864565b6125ef565b34801561078057600080fd5b506102f161078f366004614c0b565b612aa9565b3480156107a057600080fd5b5061060d6107af3660046149e6565b612c40565b3480156107c057600080fd5b506102f16107cf3660046149e6565b612ca8565b3480156107e057600080fd5b5061033d6107ef366004614626565b612e1e565b61033d610802366004614c4e565b61316e565b34801561081357600080fd5b5061033d613197565b34801561082857600080fd5b5061083c6108373660046149e6565b61319d565b6040516102d59190614ee2565b34801561085557600080fd5b506102c8610864366004614c2d565b61320a565b34801561087557600080fd5b506102f16108843660046145ee565b6132a6565b34801561089557600080fd5b506102f16108a4366004614ced565b6132f2565b3480156108b557600080fd5b506108c96108c43660046149e6565b613394565b6040516102d596959493929190614e21565b6102f16108e93660046147d1565b61362a565b600154600160a01b900460ff1681565b60005b8281101561097e57600084848381811061092b57634e487b7160e01b600052603260045260246000fd5b9050608002018036038101906109419190614a73565b9050610969816000015182602001516001600160e81b03168360400151846060015187613647565b5050808061097690615574565b915050610901565b5047156109b35760405133904780156108fc02916000818181858888f193505050501580156109b1573d6000803e3d6000fd5b505b505050565b6000806000806000806109c961421f565b6000808960028054905081106109fa5760405162461bcd60e51b81526004016109f1906152e4565b60405180910390fd5b600060028c81548110610a1d57634e487b7160e01b600052603260045260246000fd5b60009182526020808320604080516101608101825260069490940290910180546001600160a01b0381168552600160a01b810460ff90811686860152600160a81b8204811686850152600160b01b8204166060860152600160b81b90046001600160481b03166080850152600181015461ffff80821660a08701526201000082041660c0860152640100000000900490921b63ffffffff191660e0808501919091528151908101918290529293919261010085019290916002850191600791908390855b82829054906101000a900460c01b6001600160c01b03191681526020019060080190602082600701049283019260010382029150808411610ae15750505092845250506040805160808101918290526020909301929150600484810191826000855b82829054906101000a900460f01b6001600160f01b03191681526020019060020190602082600101049283019260010382029150808411610b4357905050505050508152602001600582018054610b999061553f565b80601f0160208091040260200160405190810160405280929190818152602001828054610bc59061553f565b8015610c125780601f10610be757610100808354040283529160200191610c12565b820191906000526020600020905b815481529060010190602001808311610bf557829003601f168201915b5050505050815250509050610c268c61120f565b955060006001600160481b03801682608001516001600160481b031614158015610c58575060008260c0015161ffff16115b90508160a001518260c001518360e00151846000015185606001518b876101200151878960800151806001600160481b031690509b509b509b509b509b509b509b509b509b505050509193959799909294969850565b600a5481565b6008546001600160a01b03163314610cde5760405162461bcd60e51b81526004016109f1906152c0565b600854604051632142170760e11b81526001600160a01b03808516926342842e0e92610d1292309216908690600401614dfd565b600060405180830381600087803b158015610d2c57600080fd5b505af1158015610d40573d6000803e3d6000fd5b505050505050565b60095481565b8160028181548110610d7057634e487b7160e01b600052603260045260246000fd5b60009182526020909120600690910201546001600160a01b03163314610da85760405162461bcd60e51b81526004016109f190615014565b6000838152600360205260408082208151610c80810192839052610dec9290919060649082845b815481526020019060010190808311610dcf575050505050613b5e565b9050808015610df9575082155b15610e51576000848152600360205260409020610e1590613b6c565b7f1c1299472ea84a0173b453dbcef882eb9dbb148c918af8c69a0f7fe7a6c9999c84604051610e4491906153fe565b60405180910390a16109b1565b80158015610e5c5750825b156109b1576000848152600360205260409020610e7890613b79565b7faa2a220ef40a7e03eeaf1a9775f860d2a041c5a62795ff9dba2ad35d2573023284604051610ea791906153fe565b60405180910390a150505050565b8360028181548110610ed757634e487b7160e01b600052603260045260246000fd5b60009182526020909120600690910201546001600160a01b03163314610f0f5760405162461bcd60e51b81526004016109f190615014565b6000858152600360205260408120905b8381101561101957616360858583818110610f4a57634e487b7160e01b600052603260045260246000fd5b9050602002016020810190610f5f9190614b00565b61ffff1610610f805760405162461bcd60e51b81526004016109f190615177565b8515610fc957610fc482868684818110610faa57634e487b7160e01b600052603260045260246000fd5b9050602002016020810190610fbf9190614b00565b613b85565b611007565b61100782868684818110610fed57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906110029190614b00565b613bf3565b8061101181615574565b915050610f1f565b5060408051610c808101918290528254815261104d9183906064906001830160208501808311610dcf575050505050613b5e565b15610d40577faa2a220ef40a7e03eeaf1a9775f860d2a041c5a62795ff9dba2ad35d257302328660405161108191906153fe565b60405180910390a1505050505050565b600660205281600052604060002081815481106110ad57600080fd5b6000918252602090912001546001600160e81b0381169250600160e81b810460ff169150600160f01b900461ffff1683565b816002818154811061110157634e487b7160e01b600052603260045260246000fd5b60009182526020909120600690910201546001600160a01b031633146111395760405162461bcd60e51b81526004016109f190615014565b816001600160481b038111156111615760405162461bcd60e51b81526004016109f19061512a565b60006002858154811061118457634e487b7160e01b600052603260045260246000fd5b600091825260209091206006909102018054909150600160b81b90046001600160481b031684146112085780546001600160b81b0316600160b81b6001600160481b038616021781556040517ff8fe85871edbbfe8fb67b615893befdd9e238c9d24b898a4ec3d127ce0c772c7906111ff9087908790615455565b60405180910390a15b5050505050565b600254600090829081106112355760405162461bcd60e51b81526004016109f1906152e4565b60006002848154811061125857634e487b7160e01b600052603260045260246000fd5b6000918252602082206040805160e081019182905293600690930290910160020191600791908390855b82829054906101000a900460c01b6001600160c01b031916815260200190600801906020826007010492830192600103820291508084116112825790505050505050905060005b60078160ff16101561131f57818160ff16600781106112f857634e487b7160e01b600052603260045260246000fd5b602002015160c01c61130d5792506113269050565b806113178161558f565b9150506112c9565b5060079250505b50919050565b816002818154811061134e57634e487b7160e01b600052603260045260246000fd5b60009182526020909120600690910201546001600160a01b031633146113865760405162461bcd60e51b81526004016109f190615014565b816001600160a01b0381166113ad5760405162461bcd60e51b81526004016109f190615151565b6000600285815481106113d057634e487b7160e01b600052603260045260246000fd5b60009182526020808320600690920290910180546001600160a01b03168352600490915260409091209091506114069086613c62565b506001600160a01b03841660009081526004602052604090206114299086613d7f565b5080546001600160a01b0319166001600160a01b0385161781556040517f6d560cdea63129f257830d15b59a7f95afc978dd86449a0679946cd2e43b5738906111ff9087908790615407565b6000836002818154811061149957634e487b7160e01b600052603260045260246000fd5b60009182526020909120600690910201546001600160a01b031633146114d15760405162461bcd60e51b81526004016109f190615014565b600154604051630869624160e31b815287916001600160a01b031690633894ca5790829063434b1208906115099086906004016153fe565b60206040518083038186803b15801561152157600080fd5b505afa158015611535573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155991906149fe565b6040518263ffffffff1660e01b81526004016115759190614f1f565b60206040518083038186803b15801561158d57600080fd5b505afa1580156115a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c5919061460a565b6001600160a01b031673c3f733ca98e0dad0386979eb96fb1722a1a05e696001600160a01b0316146116095760405162461bcd60e51b81526004016109f190614f72565b600080546040516331a9108f60e11b81526001600160a01b0390911690636352211e9061163a9085906004016153fe565b60206040518083038186803b15801561165257600080fd5b505afa158015611666573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168a919061460a565b9050336001600160a01b0382161480611733575060005460405163020604bf60e21b81526001600160a01b039091169063081812fc906116ce9085906004016153fe565b60206040518083038186803b1580156116e657600080fd5b505afa1580156116fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171e919061460a565b6001600160a01b0316336001600160a01b0316145b806117bb575060005460405163e985e9c560e01b81526001600160a01b039091169063e985e9c59061176b9084903390600401614de3565b60206040518083038186803b15801561178357600080fd5b505afa158015611797573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117bb91906149ca565b6117d75760405162461bcd60e51b81526004016109f190615230565b6000600288815481106117fa57634e487b7160e01b600052603260045260246000fd5b600091825260209091206006909102016001015462010000900461ffff16116118355760405162461bcd60e51b81526004016109f190615095565b6002878154811061185657634e487b7160e01b600052603260045260246000fd5b60009182526020909120600690910201600101805462010000900461ffff1690600261188183615521565b91906101000a81548161ffff021916908361ffff160217905550506118a888888888613dc9565b98975050505050505050565b6008546001600160a01b031633146118de5760405162461bcd60e51b81526004016109f1906152c0565b6008546040516370a0823160e01b815282916001600160a01b038084169263a9059cbb929091169083906370a082319061191c903090600401614db6565b60206040518083038186803b15801561193457600080fd5b505afa158015611948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196c9190614b1a565b6040518363ffffffff1660e01b8152600401611989929190614dca565b602060405180830381600087803b1580156119a357600080fd5b505af11580156119b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b391906149ca565b6000806119eb8787878787613647565b90504715611a215760405133904780156108fc02916000818181858888f19350505050158015611a1f573d6000803e3d6000fd5b505b9695505050505050565b6008546001600160a01b03163314611a555760405162461bcd60e51b81526004016109f1906152c0565b600154600160a01b900460ff1615611a7f5760405162461bcd60e51b81526004016109f1906150e3565b6001805460ff60a01b1916600160a01b179055565b600080611aa88c8c8c8c8c8c8c8c8c6125ef565b6000818152600360205260409020909150611ac59084606461423d565b506000818152600360205260409020611add90613b79565b9b9a5050505050505050505050565b6008546001600160a01b03163314611b165760405162461bcd60e51b81526004016109f1906152c0565b600955565b6008546001600160a01b03163314611b455760405162461bcd60e51b81526004016109f1906152c0565b6001805460ff60a01b19169055565b6001600160a01b0381166000908152600460205260408120611b7590613fe3565b90505b919050565b6008546001600160a01b03163314611ba75760405162461bcd60e51b81526004016109f1906152c0565b600a55565b8060028181548110611bce57634e487b7160e01b600052603260045260246000fd5b60009182526020909120600690910201546001600160a01b03163314611c065760405162461bcd60e51b81526004016109f190615014565b6000828152600360205260408120611c1d9161427b565b7f1c1299472ea84a0173b453dbcef882eb9dbb148c918af8c69a0f7fe7a6c9999c82604051611c4c91906153fe565b60405180910390a15050565b6008546001600160a01b03163314611c825760405162461bcd60e51b81526004016109f1906152c0565b60008060005b83811015610d4057848482818110611cb057634e487b7160e01b600052603260045260246000fd5b905060200201359250600280549050811015611d1a5760028381548110611ce757634e487b7160e01b600052603260045260246000fd5b60009182526020909120600690910201805460ff600160b01b80830482168a179091160260ff60b01b1990911617815591505b80611d2481615574565b915050611c88565b60005b818110156109b3576000838383818110611d5957634e487b7160e01b600052603260045260246000fd5b905060800201803603810190611d6f9190614a73565b9050611d96816000015182602001516001600160e81b031683604001518460600151611f74565b5080611da181615574565b915050611d2f565b6000808383604051611dbc929190614da6565b604080519182900390912060009081526007602052205460ff16159150505b92915050565b6008546001600160a01b03163314611e0b5760405162461bcd60e51b81526004016109f1906152c0565b60008060005b83811015610d4057848482818110611e3957634e487b7160e01b600052603260045260246000fd5b905060200201359250600280549050811015611e9f5760028381548110611e7057634e487b7160e01b600052603260045260246000fd5b600091825260209091206006909102018054600160b01b808204891660ff160260ff60b01b1990911617815591505b80611ea981615574565b915050611e11565b6008546001600160a01b031681565b611ec861428d565b6000838152600660205260409020548210611ef55760405162461bcd60e51b81526004016109f190615267565b6000838152600660205260409020805483908110611f2357634e487b7160e01b600052603260045260246000fd5b60009182526020918290206040805160608101825292909101546001600160e81b0381168352600160e81b810460ff1693830193909352600160f01b90920461ffff16918101919091529392505050565b600154604051630869624160e31b815285916001600160a01b031690633894ca5790829063434b120890611fac9086906004016153fe565b60206040518083038186803b158015611fc457600080fd5b505afa158015611fd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ffc91906149fe565b6040518263ffffffff1660e01b81526004016120189190614f1f565b60206040518083038186803b15801561203057600080fd5b505afa158015612044573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612068919061460a565b6001600160a01b031673c3f733ca98e0dad0386979eb96fb1722a1a05e696001600160a01b0316146120ac5760405162461bcd60e51b81526004016109f190614f72565b600080546040516331a9108f60e11b81526001600160a01b0390911690636352211e906120dd9085906004016153fe565b60206040518083038186803b1580156120f557600080fd5b505afa158015612109573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061212d919061460a565b9050336001600160a01b03821614806121d6575060005460405163020604bf60e21b81526001600160a01b039091169063081812fc906121719085906004016153fe565b60206040518083038186803b15801561218957600080fd5b505afa15801561219d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121c1919061460a565b6001600160a01b0316336001600160a01b0316145b8061225e575060005460405163e985e9c560e01b81526001600160a01b039091169063e985e9c59061220e9084903390600401614de3565b60206040518083038186803b15801561222657600080fd5b505afa15801561223a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225e91906149ca565b61227a5760405162461bcd60e51b81526004016109f190615230565b6000868152600660205260409020805486106122a85760405162461bcd60e51b81526004016109f19061519e565b60008187815481106122ca57634e487b7160e01b600052603260045260246000fd5b90600052602060002001905060078660ff1611158015612369575080546002805490916001600160e81b031690811061231357634e487b7160e01b600052603260045260246000fd5b90600052602060002090600602016002018660ff166007811061234657634e487b7160e01b600052603260045260246000fd5b60048104919091015460039091166008026101000a90046001600160401b031615155b6123855760405162461bcd60e51b81526004016109f190615205565b805460ff60e81b1916600160e81b60ff881602176001600160f01b0316600160f01b61ffff871602178082556040517fb29ec167f10071d18b40fbdc0ebc48c3ff7067f80dec3b4c9cc820ef491d91cc916123f1916001600160e81b03909116908b908a908a906153a9565b60405180910390a15050505050505050565b60006002838154811061242657634e487b7160e01b600052603260045260246000fd5b9060005260206000209060060201600201826007811061245657634e487b7160e01b600052603260045260246000fd5b600491828204019190066008029054906101000a900460c01b905092915050565b60009081526006602052604090205490565b60076020526000908152604090205460ff1681565b600091825260056020908152604080842092845291905290205460ff1690565b81600281815481106124e057634e487b7160e01b600052603260045260246000fd5b60009182526020909120600690910201546001600160a01b031633146125185760405162461bcd60e51b81526004016109f190615014565b60008381526003602052604090206125329083606461423d565b50600083815260036020526040902061254a90613b79565b7faa2a220ef40a7e03eeaf1a9775f860d2a041c5a62795ff9dba2ad35d257302328360405161257991906153fe565b60405180910390a1505050565b6008546000906001600160a01b031633146125b35760405162461bcd60e51b81526004016109f1906152c0565b6000611aa88c8c8c8c8c8c8c8c8c612e1e565b6001600160a01b03821660009081526004602052604081206125e89083613fe7565b9392505050565b600154600090600160a01b900460ff161561261c5760405162461bcd60e51b81526004016109f1906150e3565b886001600160481b038111156126445760405162461bcd60e51b81526004016109f19061512a565b6007851180159061265457508415155b6126705760405162461bcd60e51b81526004016109f190614fc2565b60008961ffff1611801561268a57506163608961ffff1611155b6126a65760405162461bcd60e51b81526004016109f190614f9a565b60006126b560208d018d614d0f565b60ff161180156126d7575060006126d260408d0160208e01614d0f565b60ff16115b6126f35760405162461bcd60e51b81526004016109f190615294565b6126fd848461401f565b6002546127086142ad565b60005b878110156127e25788888281811061273357634e487b7160e01b600052603260045260246000fd5b90506020020160208101906127489190614a26565b60c01c6127675760405162461bcd60e51b81526004016109f190614f49565b88888281811061278757634e487b7160e01b600052603260045260246000fd5b905060200201602081019061279c9190614a26565b8282600781106127bc57634e487b7160e01b600052603260045260246000fd5b6001600160c01b03199092166020929092020152806127da81615574565b91505061270b565b50604080516101608101909152338152600290602081018f600060200201602081019061280f9190614d0f565b60ff1681526020018f600160200201602081019061282d9190614d0f565b60ff1681526020018f600260200201602081019061284b9190614d0f565b601f1660ff1681526020018e6001600160481b031681526020018d61ffff1681526020018d61ffff1681526020018c63ffffffff191681526020018381526020018b600480602002604051908101604052809291908260046020028082843760009201919091525050508152604080516020601f8b0181900481028201810190925289815291810191908a908a9081908401838280828437600092018290525093909452505083546001808201865594825260209182902084516006909202018054858401516040870151606088015160808901516001600160a01b03199094166001600160a01b039096169590951760ff60a01b1916600160a01b60ff938416021760ff60a81b1916600160a81b918316919091021760ff60b01b1916600160b01b9190941602929092176001600160b81b0316600160b81b6001600160481b039093169290920291909117815560a0840151948101805460c086015160e087015161ffff1990921661ffff9889161763ffff000019166201000098909116979097029690961763ffffffff166401000000009690931c959095029190911790935550610100810151909190612a0890600283019060076142cb565b50610120820151612a1f9060048084019190614365565b506101408201518051612a3c9160058401916020909101906143e8565b5050507f35b015e2255af00e1aaa29c36f7afac7799aacb512ed266fa7fc50d1aa2ed2eb82338e8e8e604051612a7695949392919061541e565b60405180910390a1336000908152600460205260409020612a979083613d7f565b50909c9b505050505050505050505050565b8160028181548110612acb57634e487b7160e01b600052603260045260246000fd5b60009182526020909120600690910201546001600160a01b03163314612b035760405162461bcd60e51b81526004016109f190615014565b60c082901c612b245760405162461bcd60e51b81526004016109f190614f49565b600060028481548110612b4757634e487b7160e01b600052603260045260246000fd5b6000918252602090912060069091020160038101549091506002820190600160801b90046001600160401b031615612b915760405162461bcd60e51b81526004016109f1906151d5565b60015b6000828260078110612bb657634e487b7160e01b600052603260045260246000fd5b60048104919091015460039091166008026101000a90046001600160401b03161115612bee5780612be681615574565b915050612b94565b84828260078110612c0f57634e487b7160e01b600052603260045260246000fd5b600491828204019190066008026101000a8154816001600160401b03021916908360c01c0217905550505050505050565b60025460009082908110612c665760405162461bcd60e51b81526004016109f1906152e4565b60028381548110612c8757634e487b7160e01b600052603260045260246000fd5b60009182526020909120600690910201546001600160a01b03169392505050565b8060028181548110612cca57634e487b7160e01b600052603260045260246000fd5b60009182526020909120600690910201546001600160a01b03163314612d025760405162461bcd60e51b81526004016109f190615014565b600060028381548110612d2557634e487b7160e01b600052603260045260246000fd5b60009182526020808320600690920290910180546001600160b81b03166001600160b81b0319178082556001600160a01b0316835260049091526040909120909150612d719084613c62565b50600080526004602052612da57f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec84613d7f565b5080546001600160a01b03191681556001810154612dcf9061ffff620100008204811691166154e7565b60018201805461ffff191661ffff929092169190911763ffff0000191690556040517ff8e6d7db3dbace9f381e0deecd8ee6b27ad7cc3b955fe909dc69208d8b276a66906125799085906153fe565b6008546000906001600160a01b03163314612e4b5760405162461bcd60e51b81526004016109f1906152c0565b600280546040805161016081019091526001600160a01b038d168152909190602080820190612e7c908e018e614d0f565b60ff168152602090810190612e979060408f01908f01614d0f565b60ff168152602001612eaf60608e0160408f01614d0f565b60ff1681526020018b6001600160481b031681526020018a61ffff1681526020018a61ffff1681526020018963ffffffff1916815260200187600780602002604051908101604052809291908260076020028082843760009201919091525050508152604080516080818101909252602090920191908a90600490839083908082843760009201919091525050508152604080516020601f890181900481028201810190925287815291810191908890889081908401838280828437600092018290525093909452505083546001808201865594825260209182902084516006909202018054858401516040870151606088015160808901516001600160a01b03199094166001600160a01b039096169590951760ff60a01b1916600160a01b60ff938416021760ff60a81b1916600160a81b918316919091021760ff60b01b1916600160b01b9190941602929092176001600160b81b0316600160b81b6001600160481b039093169290920291909117815560a0840151948101805460c086015160e087015161ffff1990921661ffff9889161763ffff000019166201000098909116979097029690961763ffffffff166401000000009690931c95909502919091179093555061010081015190919061309090600283019060076142cb565b506101208201516130a79060048084019190614365565b5061014082015180516130c49160058401916020909101906143e8565b505050600084846040516130d9929190614da6565b604080519182900382206000818152600760205291909120805460ff1916600117905591507f35b015e2255af00e1aaa29c36f7afac7799aacb512ed266fa7fc50d1aa2ed2eb906131339084908f908e908e908e9061541e565b60405180910390a16001600160a01b038c16600090815260046020526040902061315d9083613d7f565b50909b9a5050505050505050505050565b60085460009061318e9086908690869086906001600160a01b03166119db565b95945050505050565b60025490565b6131a561445c565b600254829081106131c85760405162461bcd60e51b81526004016109f1906152e4565b600083815260036020526040908190208151610c808101928390529160649082845b8154815260200190600101908083116131ea575050505050915050919050565b60008181526003602090815260408083208151610c808101928390528154815261324b93909260649160018401908501808311610dcf575050505050613b5e565b1561329d57600082815260036020526040908190208151610c808101928390526132969290919060649082845b8154815260200190600101908083116132785750505050508461408b565b9050611ddb565b50600192915050565b6008546001600160a01b031633146132d05760405162461bcd60e51b81526004016109f1906152c0565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b6008546001600160a01b0316331461331c5760405162461bcd60e51b81526004016109f1906152c0565b6002548290811061333f5760405162461bcd60e51b81526004016109f1906152e4565b60006002848154811061336257634e487b7160e01b600052603260045260246000fd5b60009182526020909120600690910201805460ff909416600160b01b0260ff60b01b1990941693909317909255505050565b61339c61421f565b6133a46142ad565b600080600060608660028054905081106133d05760405162461bcd60e51b81526004016109f1906152e4565b6000600289815481106133f357634e487b7160e01b600052603260045260246000fd5b60009182526020808320604080516101608101825260069490940290910180546001600160a01b0381168552600160a01b810460ff90811686860152600160a81b8204811686850152600160b01b8204166060860152600160b81b90046001600160481b03166080850152600181015461ffff80821660a08701526201000082041660c0860152640100000000900490921b63ffffffff191660e0808501919091528151908101918290529293919261010085019290916002850191600791908390855b82829054906101000a900460c01b6001600160c01b031916815260200190600801906020826007010492830192600103820291508084116134b75750505092845250506040805160808101918290526020909301929150600484810191826000855b82829054906101000a900460f01b6001600160f01b031916815260200190600201906020826001010492830192600103820291508084116135195790505050505050815260200160058201805461356f9061553f565b80601f016020809104026020016040519081016040528092919081815260200182805461359b9061553f565b80156135e85780601f106135bd576101008083540402835291602001916135e8565b820191906000526020600020905b8154815290600101906020018083116135cb57829003601f168201915b5050509190925250505061012081015161010082015160208301516040840151606085015161014090950151939e929d50909b50995091975095509350505050565b60085461364390839083906001600160a01b03166108fe565b5050565b600154604051630869624160e31b815260009187916001600160a01b0390911690633894ca5790829063434b1208906136849086906004016153fe565b60206040518083038186803b15801561369c57600080fd5b505afa1580156136b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d491906149fe565b6040518263ffffffff1660e01b81526004016136f09190614f1f565b60206040518083038186803b15801561370857600080fd5b505afa15801561371c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613740919061460a565b6001600160a01b031673c3f733ca98e0dad0386979eb96fb1722a1a05e696001600160a01b0316146137845760405162461bcd60e51b81526004016109f190614f72565b600080546040516331a9108f60e11b81526001600160a01b0390911690636352211e906137b59085906004016153fe565b60206040518083038186803b1580156137cd57600080fd5b505afa1580156137e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613805919061460a565b9050336001600160a01b03821614806138ae575060005460405163020604bf60e21b81526001600160a01b039091169063081812fc906138499085906004016153fe565b60206040518083038186803b15801561386157600080fd5b505afa158015613875573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613899919061460a565b6001600160a01b0316336001600160a01b0316145b80613936575060005460405163e985e9c560e01b81526001600160a01b039091169063e985e9c5906138e69084903390600401614de3565b60206040518083038186803b1580156138fe57600080fd5b505afa158015613912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061393691906149ca565b6139525760405162461bcd60e51b81526004016109f190615230565b836001600160a01b0381166139795760405162461bcd60e51b81526004016109f190615151565b6002548890811061399c5760405162461bcd60e51b81526004016109f1906152e4565b6139a68a8a61320a565b6139c25760405162461bcd60e51b81526004016109f1906150bf565b600060028a815481106139e557634e487b7160e01b600052603260045260246000fd5b600091825260209091206006909102018054909150600160b81b90046001600160481b039081161415613a2a5760405162461bcd60e51b81526004016109f19061506f565b600181015462010000900461ffff16613a555760405162461bcd60e51b81526004016109f190615095565b60018101805462010000900461ffff16906002613a7183615521565b825461ffff9182166101009390930a92830291909202199091161790555080546001600160481b03600160b81b90910416471015613ac15760405162461bcd60e51b81526004016109f190615043565b80546040517f60c51beec34453d79798ec1b796eff7f0700ff9a3679cb3e77b79e7abc23db7291613b07918d918f91600160b81b9091046001600160481b031690615463565b60405180910390a16000613b1d8c8c8c8c613dc9565b8254909150600160b81b90046001600160481b031615611add578154611add906001600160a01b03811690600160b81b90046001600160481b03168a6140f0565b610c60015160019081161490565b6063018054600119169055565b60630180546001179055565b6000613b93610100836154b2565b90506000613ba3610100846155af565b90506000613bb28260ff6154e7565b61ffff16600160001b901b905080858461ffff1660648110613be457634e487b7160e01b600052603260045260246000fd5b01805490911790555050505050565b6000613c01610100836154b2565b90506000613c11610100846155af565b90506000613c208260ff6154e7565b61ffff16600160001b901b19905080858461ffff1660648110613c5357634e487b7160e01b600052603260045260246000fd5b01805490911690555050505050565b60008181526001830160205260408120548015613d75576000613c8660018361550a565b8554909150600090613c9a9060019061550a565b9050818114613d1b576000866000018281548110613cc857634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905080876000018481548110613cf957634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613d3a57634e487b7160e01b600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611ddb565b6000915050611ddb565b6000613d8b8383614207565b613dc157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611ddb565b506000611ddb565b60025460009084908110613def5760405162461bcd60e51b81526004016109f1906152e4565b600154600160a01b900460ff1615613e195760405162461bcd60e51b81526004016109f1906150e3565b600086815260056020908152604080832088845290915290205460ff1615613e535760405162461bcd60e51b81526004016109f190615103565b60028581548110613e7457634e487b7160e01b600052603260045260246000fd5b90600052602060002090600602016002018460ff1660078110613ea757634e487b7160e01b600052603260045260246000fd5b60048104919091015460039091166008026101000a90046001600160401b0316613ee35760405162461bcd60e51b81526004016109f190614f49565b6000868152600660209081526040808320805482516060810184526001600160e81b038b8116825260ff8b811683880190815261ffff8c811685890190815260018088018955888c528a8c2096519688018054945192516001600160e81b0319909516979096169690961760ff60e81b1916600160e81b9190941602929092176001600160f01b0316600160f01b91909216021790558b8652600585528386208b875290945293829020805460ff1916909317909255519091907fb29ec167f10071d18b40fbdc0ebc48c3ff7067f80dec3b4c9cc820ef491d91cc90613fd09089908b908a908a90615482565b60405180910390a1979650505050505050565b5490565b600082600001828154811061400c57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b60008282604051614031929190614da6565b604080519182900390912060008181526007602052919091205490915060ff161561406e5760405162461bcd60e51b81526004016109f190614ff1565b6000908152600760205260409020805460ff191660011790555050565b60008061409a610100846154d3565b905060006140aa610100856155d0565b905060006140b98260ff61550a565b6001901b90508583606481106140df57634e487b7160e01b600052603260045260246000fd5b602002015116151595945050505050565b6000806009541161410257600061410f565b60095461410f90846154d3565b9050600080600a5411614123576000614130565b600a5461413090836154d3565b905061413c818361550a565b915060008161414b848761550a565b614155919061550a565b6008546040519192506001600160a01b03169084156108fc029085906000818181858888f19350505050158015614190573d6000803e3d6000fd5b506040516001600160a01b0385169083156108fc029084906000818181858888f193505050501580156141c7573d6000803e3d6000fd5b506040516001600160a01b0387169082156108fc029083906000818181858888f193505050501580156141fe573d6000803e3d6000fd5b50505050505050565b60009081526001919091016020526040902054151590565b60405180608001604052806004906020820280368337509192915050565b826064810192821561426b579160200282015b8281111561426b578235825591602001919060010190614250565b5061427792915061447b565b5090565b5061428a90606481019061447b565b50565b604080516060810182526000808252602082018190529181019190915290565b6040518060e001604052806007906020820280368337509192915050565b60028301918390821561426b5791602002820160005b8382111561432557835183826101000a8154816001600160401b03021916908360c01c021790555092602001926008016020816007010492830192600103026142e1565b80156143585782816101000a8154906001600160401b030219169055600801602081600701049283019260010302614325565b505061427792915061447b565b60018301918390821561426b5791602002820160005b838211156143ba57835183826101000a81548161ffff021916908360f01c0217905550926020019260020160208160010104928301926001030261437b565b80156143585782816101000a81549061ffff02191690556002016020816001010492830192600103026143ba565b8280546143f49061553f565b90600052602060002090601f016020900481019282614416576000855561426b565b82601f1061442f57805160ff191683800117855561426b565b8280016001018555821561426b579182015b8281111561426b578251825591602001919060010190614441565b60405180610c8001604052806064906020820280368337509192915050565b5b80821115614277576000815560010161447c565b8060808101831015611ddb57600080fd5b80610c808101831015611ddb57600080fd5b8060e08101831015611ddb57600080fd5b60008083601f8401126144d5578182fd5b5081356001600160401b038111156144eb578182fd5b602083019150836020808302850101111561450557600080fd5b9250929050565b60008083601f84011261451d578182fd5b5081356001600160401b03811115614533578182fd5b60208301915083602060808302850101111561450557600080fd5b8060608101831015611ddb57600080fd5b803563ffffffff1981168114611b7857600080fd5b80356001600160c01b031981168114611b7857600080fd5b60008083601f84011261459d578182fd5b5081356001600160401b038111156145b3578182fd5b60208301915083602082850101111561450557600080fd5b803561ffff81168114611b7857600080fd5b803560ff81168114611b7857600080fd5b6000602082840312156145ff578081fd5b81356125e881615610565b60006020828403121561461b578081fd5b81516125e881615610565b60008060008060008060008060006102608a8c031215614644578485fd5b893561464f81615610565b985061465e8b60208c0161454e565b975060808a0135965061467360a08b016145cb565b955061468160c08b0161455f565b94506146908b60e08c01614490565b93506146a08b6101608c016144b3565b92506102408a01356001600160401b038111156146bb578283fd5b6146c78c828d0161458c565b915080935050809150509295985092959850929598565b600080600080600080600080600080610ee08b8d0312156146fd578384fd5b8a3561470881615610565b99506147178c60208d0161454e565b985060808b0135975061472c60a08c016145cb565b965061473a60c08c0161455f565b95506147498c60e08d01614490565b94506147598c6101608d016144b3565b93506102408b01356001600160401b03811115614774578182fd5b6147808d828e0161458c565b909450925061479590508c6102608d016144a1565b90509295989b9194979a5092959850565b600080604083850312156147b8578182fd5b82356147c381615610565b946020939093013593505050565b600080602083850312156147e3578182fd5b82356001600160401b038111156147f8578283fd5b6148048582860161450c565b90969095509350505050565b600080600060408486031215614824578081fd5b83356001600160401b03811115614839578182fd5b6148458682870161450c565b909450925050602084013561485981615610565b809150509250925092565b60008060008060008060008060006101808a8c031215614882578283fd5b61488c8b8b61454e565b985060608a013597506148a160808b016145cb565b96506148af60a08b0161455f565b95506148be8b60c08c01614490565b94506101408a01356001600160401b03808211156148da578485fd5b6148e68d838e016144c4565b90965094506101608c01359150808211156148ff578384fd5b506146c78c828d0161458c565b600080600080600080600080600080610e008b8d03121561492b578384fd5b6149358c8c61454e565b995060608b0135985061494a60808c016145cb565b975061495860a08c0161455f565b96506149678c60c08d01614490565b95506101408b01356001600160401b0380821115614983578586fd5b61498f8e838f016144c4565b90975095506101608d01359150808211156149a8578485fd5b506149b58d828e0161458c565b909450925061479590508c6101808d016144a1565b6000602082840312156149db578081fd5b81516125e881615625565b6000602082840312156149f7578081fd5b5035919050565b600060208284031215614a0f578081fd5b81516001600160d81b0319811681146125e8578182fd5b600060208284031215614a37578081fd5b6125e882614574565b60008060208385031215614a52578182fd5b82356001600160401b03811115614a67578283fd5b6148048582860161458c565b600060808284031215614a84578081fd5b604051608081018181106001600160401b0382111715614ab257634e487b7160e01b83526041600452602483fd5b6040528235815260208301356001600160e81b0381168114614ad2578283fd5b6020820152614ae3604084016145dd565b6040820152614af4606084016145cb565b60608201529392505050565b600060208284031215614b11578081fd5b6125e8826145cb565b600060208284031215614b2b578081fd5b5051919050565b60008060408385031215614b44578182fd5b823591506020830135614b5681615610565b809150509250929050565b600080610ca08385031215614b74578182fd5b82359150614b8584602085016144a1565b90509250929050565b60008060408385031215614ba0578182fd5b823591506020830135614b5681615625565b60008060008060608587031215614bc7578182fd5b843593506020850135614bd981615625565b925060408501356001600160401b03811115614bf3578283fd5b614bff878288016144c4565b95989497509550505050565b60008060408385031215614c1d578182fd5b82359150614b8560208401614574565b60008060408385031215614c3f578182fd5b50508035926020909101359150565b60008060008060808587031215614c63578182fd5b8435935060208501359250614c7a604086016145dd565b9150614c88606086016145cb565b905092959194509250565b600080600080600060a08688031215614caa578283fd5b8535945060208601359350614cc1604087016145dd565b9250614ccf606087016145cb565b91506080860135614cdf81615610565b809150509295509295909350565b60008060408385031215614cff578182fd5b82359150614b85602084016145dd565b600060208284031215614d20578081fd5b6125e8826145dd565b600080600060408486031215614d3d578081fd5b614d46846145dd565b925060208401356001600160401b03811115614d60578182fd5b614d6c868287016144c4565b9497909650939450505050565b8060005b60048110156109b15781516001600160f01b031916845260209384019390910190600101614d7d565b6000828483379101908152919050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60006101e0614e30838a614d79565b6080830188835b6007811015614e605781516001600160c01b031916835260209283019290910190600101614e37565b50505060ff871661016084015260ff861661018084015260ff85166101a0840152806101c0840152835180828501528291505b80821015614eb557602082860101516102008386010152602082019150614e93565b80821115614ec7578261020082860101525b601f01601f1916929092016102000198975050505050505050565b610c808101818360005b6064811015614f0b578151835260209283019290910190600101614eec565b50505092915050565b901515815260200190565b6001600160d81b031991909116815260200190565b6001600160c01b031991909116815260200190565b6020808252600f908201526e496e76616c69642050616c6574746560881b604082015260600190565b6020808252600e908201526d139bdd081058d8db1a5b585d195960921b604082015260600190565b6020808252600e908201526d496e76616c696420537570706c7960901b604082015260600190565b602080825260159082015274125b9d985b1a590814185b195d1d194810dbdd5b9d605a1b604082015260600190565b6020808252600990820152684475706c696361746560b81b604082015260600190565b6020808252601590820152742737ba1020b1b1b2b9b9b7b93c9026b0b730b3b2b960591b604082015260600190565b602080825260129082015271496e73756666696369656e742056616c756560701b604082015260600190565b6020808252600c908201526b4e6f7420466f722053616c6560a01b604082015260600190565b60208082526010908201526f14dd5c1c1b1e48115e1a185d5cdd195960821b604082015260600190565b6020808252600a9082015269496e656c696769626c6560b01b604082015260600190565b602080825260069082015265233937bd32b760d11b604082015260600190565b6020808252600d908201526c105b1c9958591e4813dddb9959609a1b604082015260600190565b6020808252600d908201526c496e76616c696420507269636560981b604082015260600190565b6020808252600c908201526b5a65726f204164647265737360a01b604082015260600190565b6020808252600d908201526c4f7574206f6620626f756e647360981b604082015260600190565b60208082526019908201527f4f776e6564204163636573736f7279204e6f7420466f756e6400000000000000604082015260600190565b60208082526016908201527514185b195d1d1948131a5b5a5d08115e18d95959195960521b604082015260600190565b60208082526011908201527014185b195d1d1948139bdd08119bdd5b99607a1b604082015260600190565b60208082526019908201527f4e6f7420414d43204f776e6572206f7220417070726f76656400000000000000604082015260600190565b602080825260139082015272496e646578206f7574206f6620626f756e647360681b604082015260600190565b602080825260129082015271496e76616c69642044696d656e73696f6e7360701b604082015260600190565b6020808252600a908201526927b7363c9027bbb732b960b11b604082015260600190565b6020808252601390820152721058d8d95cdcdbdc9e48139bdd08119bdd5b99606a1b604082015260600190565b81516001600160e81b0316815260208083015160ff169082015260409182015161ffff169181019190915260600190565b61ffff8a811682528916602082015263ffffffff19881660408201526001600160a01b038716606082015260ff8681166080830152851660a0820152610180810161539060c0830186614d79565b9215156101408201526101600152979650505050505050565b6001600160e81b03949094168452602084019290925260ff16604083015261ffff16606082015260800190565b6001600160e81b0393909316835260ff91909116602083015261ffff16604082015260600190565b90815260200190565b9182526001600160a01b0316602082015260400190565b9485526001600160a01b03939093166020850152604084019190915261ffff16606083015263ffffffff1916608082015260a00190565b918252602082015260400190565b92835260208301919091526001600160481b0316604082015260600190565b938452602084019290925260ff16604083015261ffff16606082015260800190565b60ff91909116815260200190565b600061ffff808416806154c7576154c76155fa565b92169190910492915050565b6000826154e2576154e26155fa565b500490565b600061ffff83811690831681811015615502576155026155e4565b039392505050565b60008282101561551c5761551c6155e4565b500390565b600061ffff821680615535576155356155e4565b6000190192915050565b60028104600182168061555357607f821691505b6020821081141561132657634e487b7160e01b600052602260045260246000fd5b6000600019821415615588576155886155e4565b5060010190565b600060ff821660ff8114156155a6576155a66155e4565b60010192915050565b600061ffff808416806155c4576155c46155fa565b92169190910692915050565b6000826155df576155df6155fa565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b6001600160a01b038116811461428a57600080fd5b801515811461428a57600080fdfea264697066735822122001a3f04d7fcae1dc1d847527809bb1c1ca6c826ccf153571c48e40e4e7b3807a64736f6c63430008010033

Verified Source Code Partial Match

Compiler: v0.8.1+commit.df193b15 EVM: istanbul Optimization: Yes (200 runs)
MoonCatAccessories.sol 990 lines
// SPDX-License-Identifier: AGPL-3.0

pragma solidity 0.8.1;

interface IMoonCatAcclimator {
    function getApproved(uint256 tokenId) external view returns (address);
    function isApprovedForAll(address owner, address operator) external view returns (bool);
    function ownerOf(uint256 tokenId) external view returns (address);
}

interface IMoonCatRescue {
    function rescueOrder(uint256 tokenId) external view returns (bytes5);
    function catOwners(bytes5 catId) external view returns (address);
}

interface IReverseResolver {
    function claim(address owner) external returns (bytes32);
}

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
}
interface IERC721 {
    function safeTransferFrom(address from, address to, uint256 tokenId) external;
}

/**
 * @dev Derived from OpenZeppelin standard template
 * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/EnumerableSet.sol
 * b0cf6fbb7a70f31527f36579ad644e1cf12fdf4e
 */
library EnumerableSet {
    struct Set {
        uint256[] _values;
        mapping (uint256 => uint256) _indexes;
    }

    function at(Set storage set, uint256 index) internal view returns (uint256) {
        return set._values[index];
    }

    function contains(Set storage set, uint256 value) internal view returns (bool) {
        return set._indexes[value] != 0;
    }

    function length(Set storage set) internal view returns (uint256) {
        return set._values.length;
    }

    function add(Set storage set, uint256 value) internal returns (bool) {
        if (!contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    function remove(Set storage set, uint256 value) internal returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];
        if (valueIndex != 0) { // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.
            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;
            if (lastIndex != toDeleteIndex) {
                uint256 lastvalue = set._values[lastIndex];
                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastvalue;
                // Update the index for the moved value
                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();
            // Delete the index for the deleted slot
            delete set._indexes[value];
            return true;
        } else {
            return false;
        }
    }
}

library MoonCatBitSet {

    bytes32 constant Mask =  0x0000000000000000000000000000000000000000000000000000000000000001;

    function activate(bytes32[100] storage set)
        internal
    {
        set[99] |= Mask;
    }

    function deactivate(bytes32[100] storage set)
        internal
    {
        set[99] &= ~Mask;
    }

    function setBit(bytes32[100] storage set, uint16 index)
        internal
    {
        uint16 wordIndex = index / 256;
        uint16 bitIndex = index % 256;
        bytes32 mask = Mask << (255 - bitIndex);
        set[wordIndex] |= mask;
    }

    function clearBit(bytes32[100] storage set, uint16 index)
        internal
    {
        uint16 wordIndex = index / 256;
        uint16 bitIndex = index % 256;
        bytes32 mask = ~(Mask << (255 - bitIndex));
        set[wordIndex] &= mask;
    }

    function checkBit(bytes32[100] memory set, uint256 index)
        internal
        pure
        returns (bool)
    {
        uint256 wordIndex = index / 256;
        uint256 bitIndex = index % 256;
        bytes32 mask = Mask << (255 - bitIndex);
        return (mask & set[wordIndex]) != 0;
    }

    function isActive(bytes32[100] memory set)
        internal
        pure
        returns (bool)
    {
        return (Mask & set[99]) == Mask;
    }
}


/**
 * @title MoonCat​Accessories
 * @notice Public MoonCat Wearables infrastructure/protocols
 * @dev Allows wearable-designers to create accessories for sale and gifting.
 */
contract MoonCatAccessories {

    /* External Contracts */

    IMoonCatAcclimator MCA = IMoonCatAcclimator(0xc3f733ca98E0daD0386979Eb96fb1722A1A05E69);
    IMoonCatRescue MCR = IMoonCatRescue(0x60cd862c9C687A9dE49aecdC3A99b74A4fc54aB6);

    /* Events */

    event AccessoryCreated(uint256 accessoryId, address creator, uint256 price, uint16 totalSupply, bytes30 name);
    event AccessoryManagementTransferred(uint256 accessoryId, address newManager);
    event AccessoryPriceChanged(uint256 accessoryId, uint256 price);
    event AccessoryPurchased(uint256 accessoryId, uint256 rescueOrder, uint256 price);
    event AccessoryApplied(uint256 accessoryId, uint256 rescueOrder, uint8 paletteIndex, uint16 zIndex);
    event AccessoryDiscontinued(uint256 accessoryId);

    event EligibleListSet(uint256 accessoryId);
    event EligibleListCleared(uint256 accessoryId);

    /* Structs */

    struct Accessory {            // Accessory Definition
        address payable manager;  // initially creator; payee for sales
        uint8 width;              // image width
        uint8 height;             // image height
        uint8 meta;               // metadata flags [Reserved 3b, Audience 2b, MirrorPlacement 1b, MirrorAccessory 1b, Background 1b]
        uint72 price;             // price at which accessory can be purchased (MAX ~4,722 ETH)
                                  // if set to max value, the accessory is not for sale

        uint16 totalSupply;      // total number of a given accessory that will ever exist; can only be changed by discontinuing the accessory
        uint16 availableSupply;  // number of given accessory still available for sale; decremented on each sale
        bytes28 name;            // unicode name of accessory, can only be set on creation

        bytes8[7] palettes;     // color palettes, each palette is an array of uint8 offsets into the global palette
        bytes2[4] positions;    // offsets for all 4 MoonCat poses, an offset pair of 0xffff indicates the pose is not supported
                                // position order is [standing, sleeping, pouncing, stalking]

        bytes IDAT;            // PNG IDAT chunk data for image reconstruction
    }

    struct OwnedAccessory {   // Accessory owned by an AcclimatedMoonCat
        uint232 accessoryId;  // index into AllAccessories Array
        uint8 paletteIndex;   // index into Accessory.palettes Array
        uint16 zIndex;        // drawing order indicator (lower numbers are closer to MoonCat)
                              // zIndex == 0 indicates the MoonCat is not wearing the accessory
                              // if the accessory meta `Background` bit is 1 the zIndex is interpreted as negative
    }

    struct AccessoryBatchData {   // Used for batch accessory alterations and purchases
        uint256 rescueOrder;
        uint232 ownedIndexOrAccessoryId;
        uint8 paletteIndex;
        uint16 zIndex;
    }

    using EnumerableSet for EnumerableSet.Set;

    /* State */

    bool public frozen = true;

    Accessory[] internal AllAccessories; //  Array of all Accessories that have been created
    mapping (uint256 => bytes32[100]) internal AllEligibleLists; // Accessory ID => BitSet
                                                                 // Each bit represents the eligbility of an AcclimatedMoonCat
                                                                 // An eligibleList is active when the final bit == 1

    mapping (address => EnumerableSet.Set) internal AccessoriesByManager; // Manager address => accessoryId Set

    mapping (uint256 => mapping(uint256 => bool)) internal OwnedAccessoriesByMoonCat; // AcclimatedMoonCat rescueOrder => Accessory ID => isOwned?
    mapping (uint256 => OwnedAccessory[]) public AccessoriesByMoonCat; // AcclimatedMoonCat rescueOrder => Array of AppliedAccessory structs

    mapping (bytes32 => bool) public accessoryHashes; // used to check if the image data for an accessory has already been submitted

    address payable public owner;

    uint72 constant NOT_FOR_SALE = 0xffffffffffffffffff;

    uint256 public feeDenominator = 5;
    uint256 public referralDenominator = 0;

    /* Modifiers */

    modifier onlyOwner () {
        require(msg.sender == owner, "Only Owner");
        _;
    }

    modifier accessoryExists (uint256 accessoryId){
        require(accessoryId < AllAccessories.length, "Accessory Not Found");
        _;
    }

    modifier onlyAccessoryManager (uint256 accessoryId) {
        require(msg.sender == AllAccessories[accessoryId].manager, "Not Accessory Manager");
        _;
    }

    modifier onlyAMCOwner (uint256 rescueOrder) {
        require(MCR.catOwners(MCR.rescueOrder(rescueOrder)) == 0xc3f733ca98E0daD0386979Eb96fb1722A1A05E69,
                "Not Acclimated");
        address moonCatOwner = MCA.ownerOf(rescueOrder);
        require((msg.sender == moonCatOwner)
            || (msg.sender == MCA.getApproved(rescueOrder))
            || (MCA.isApprovedForAll(moonCatOwner, msg.sender)),
            "Not AMC Owner or Approved"
        );
        _;
    }

    modifier notZeroAddress (address a){
        require(a != address(0), "Zero Address");
        _;
    }

    modifier notFrozen () {
        require(!frozen, "Frozen");
        _;
    }

    modifier validPrice(uint256 price) {
        require(price <= NOT_FOR_SALE, "Invalid Price");
        _;
    }

    /* Admin */

    constructor(){
        owner = payable(msg.sender);

        // https://docs.ens.domains/contract-api-reference/reverseregistrar#claim-address
        IReverseResolver(0x084b1c3C81545d370f3634392De611CaaBFf8148)
            .claim(msg.sender);
    }

    /**
     * @dev Transfer funds from the contract's wallet to an external wallet, minus a fee
     */
    function sendPayment (address payable target, uint256 amount, address payable referrer)
        internal
    {
        uint256 fee = (feeDenominator > 0) ? (amount / feeDenominator) : 0;
        uint256 referral = (referralDenominator > 0) ? (fee / referralDenominator) : 0;
        fee = fee - referral;
        uint256 payment = amount - fee - referral;
        owner.transfer(fee);
        referrer.transfer(referral);
        target.transfer(payment);
    }

    /**
     * @dev Update the amount of fee taken from each sale
     */
    function setFee (uint256 denominator)
        public
        onlyOwner
    {
        feeDenominator = denominator;
    }

    /**
     * @dev Update the amount of referral fee taken from each sale
     */
    function setReferralFee (uint256 denominator)
        public
        onlyOwner
    {
        referralDenominator = denominator;
    }

    /**
     * @dev Allow current `owner` to transfer ownership to another address
     */
    function transferOwnership (address payable newOwner)
        public
        onlyOwner
    {
        owner = newOwner;
    }

    /**
     * @dev Prevent creating and applying accessories
     */
    function freeze ()
        public
        onlyOwner
        notFrozen
    {
        frozen = true;
    }

    /**
     * @dev Enable creating and applying accessories
     */
    function unfreeze ()
        public
        onlyOwner
    {
        frozen = false;
    }

    /**
     * @dev Update the metadata flags for an accessory
     */
    function setMetaByte (uint256 accessoryId, uint8 metabyte)
        public
        onlyOwner
        accessoryExists(accessoryId)
    {
        Accessory storage accessory = AllAccessories[accessoryId];
        accessory.meta = metabyte;
    }

    /**
     * @dev Batch-update metabytes for accessories, by ensuring given bits are on
     */
    function batchOrMetaByte (uint8 value, uint256[] calldata accessoryIds)
        public
        onlyOwner
    {
        uint256 id;
        Accessory storage accessory;
        for(uint256 i = 0; i < accessoryIds.length; i++){
            id = accessoryIds[i];
            if(i < AllAccessories.length){
                accessory = AllAccessories[id];
                accessory.meta = accessory.meta | value;
            }
        }
    }

    /**
     * @dev Batch-update metabytes for accessories, by ensuring given bits are off
     */
    function batchAndMetaByte (uint8 value, uint256[] calldata accessoryIds)
        public
        onlyOwner
    {
        uint256 id;
        Accessory storage accessory;
        for(uint256 i = 0; i < accessoryIds.length; i++){
            id = accessoryIds[i];
            if(i < AllAccessories.length){
                accessory = AllAccessories[id];
                accessory.meta = accessory.meta & value;
            }
        }
    }

    /**
     * @dev Rescue ERC20 assets sent directly to this contract.
     */
    function withdrawForeignERC20(address tokenContract)
        public
        onlyOwner
    {
        IERC20 token = IERC20(tokenContract);
        token.transfer(owner, token.balanceOf(address(this)));
    }

    /**
     * @dev Rescue ERC721 assets sent directly to this contract.
     */
    function withdrawForeignERC721(address tokenContract, uint256 tokenId)
        public
        onlyOwner
    {
        IERC721(tokenContract).safeTransferFrom(address(this), owner, tokenId);
    }

    /**
     * @dev Check if a MoonCat is eligible to purchase an accessory
     */
    function isEligible(uint256 rescueOrder, uint256 accessoryId)
        public
        view
        returns (bool)
    {
        if(MoonCatBitSet.isActive(AllEligibleLists[accessoryId])) {
            return MoonCatBitSet.checkBit(AllEligibleLists[accessoryId], rescueOrder);
        }
        return true;
    }

    /* Helpers */

    /**
     * @dev Mark an accessory as owned by a specific MoonCat, and put it on
     *
     * This is an internal function that only does sanity-checking (prevent double-buying an accessory, and prevent picking an invalid palette).
     * All methods that use this function check permissions before calling this function.
     */
    function applyAccessory (uint256 rescueOrder, uint256 accessoryId, uint8 paletteIndex, uint16 zIndex)
        private
        accessoryExists(accessoryId)
        notFrozen
        returns (uint256)
    {
        require(OwnedAccessoriesByMoonCat[rescueOrder][accessoryId] == false, "Already Owned");
        require(uint64(AllAccessories[accessoryId].palettes[paletteIndex]) != 0, "Invalid Palette");
        OwnedAccessory[] storage ownedAccessories = AccessoriesByMoonCat[rescueOrder];
        uint256 ownedAccessoryIndex = ownedAccessories.length;
        ownedAccessories.push(OwnedAccessory(uint232(accessoryId), paletteIndex, zIndex));
        OwnedAccessoriesByMoonCat[rescueOrder][accessoryId] = true;
        emit AccessoryApplied(accessoryId, rescueOrder, paletteIndex, zIndex);
        return ownedAccessoryIndex;
    }

    /**
     * @dev Ensure an accessory's image data has not been submitted before
     */
    function verifyAccessoryUniqueness(bytes calldata IDAT)
        internal
    {
        bytes32 accessoryHash = keccak256(IDAT);
        require(!accessoryHashes[accessoryHash], "Duplicate");
        accessoryHashes[accessoryHash] = true;
    }

    /* Creator */

    /**
     * @dev Create an accessory, as the contract owner
     *
     * This method allows the contract owner to deploy accessories on behalf of others. It also allows deploying
     * accessories that break some of the rules:
     *
     * This method can be called when frozen, so the owner can add to the store even when others cannot.
     * This method does not check for duplicates, so if an accessory creator wants to make a literal duplicate, that can be facilitated.
     */
    function ownerCreateAccessory(address payable manager, uint8[3] calldata WHM, uint256 priceWei, uint16 totalSupply, bytes28 name, bytes2[4] calldata positions, bytes8[7] calldata initialPalettes, bytes calldata IDAT)
        public
        onlyOwner
        returns (uint256)
    {
        uint256 accessoryId = AllAccessories.length;
        AllAccessories.push(Accessory(manager, WHM[0], WHM[1], WHM[2], uint72(priceWei), totalSupply, totalSupply, name, initialPalettes, positions, IDAT));

        bytes32 accessoryHash = keccak256(IDAT);
        accessoryHashes[accessoryHash] = true;

        emit AccessoryCreated(accessoryId, manager, priceWei, totalSupply, name);
        AccessoriesByManager[manager].add(accessoryId);
        return accessoryId;
    }

    /**
     * @dev Create an accessory with an eligible list, as the contract owner
     */
    function ownerCreateAccessory(address payable manager, uint8[3] calldata WHM, uint256 priceWei, uint16 totalSupply, bytes28 name, bytes2[4] calldata positions, bytes8[7] calldata initialPalettes, bytes calldata IDAT, bytes32[100] calldata eligibleList)
        public
        onlyOwner
        returns (uint256)
    {
        uint256 accessoryId = ownerCreateAccessory(manager, WHM, priceWei, totalSupply, name, positions, initialPalettes, IDAT);
        AllEligibleLists[accessoryId] = eligibleList;
        MoonCatBitSet.activate(AllEligibleLists[accessoryId]);
        return accessoryId;
    }

    /**
     * @dev Create an accessory
     */
    function createAccessory (uint8[3] calldata WHM, uint256 priceWei, uint16 totalSupply, bytes28 name, bytes2[4] calldata positions, bytes8[] calldata palettes, bytes calldata IDAT)
        public
        notFrozen
        validPrice(priceWei)
        returns (uint256)
    {
        require(palettes.length <= 7 && palettes.length > 0, "Invalid Palette Count");
        require(totalSupply > 0 && totalSupply <= 25440, "Invalid Supply");
        require(WHM[0] > 0 && WHM[1] > 0, "Invalid Dimensions");
        verifyAccessoryUniqueness(IDAT);
        uint256 accessoryId = AllAccessories.length;
        bytes8[7] memory initialPalettes;
        for(uint i = 0; i < palettes.length; i++){
            require(uint64(palettes[i]) != 0, "Invalid Palette");
            initialPalettes[i] = palettes[i];
        }
        AllAccessories.push(Accessory(payable(msg.sender), WHM[0], WHM[1], WHM[2] & 0x1f, uint72(priceWei), totalSupply, totalSupply, name, initialPalettes, positions, IDAT));
        //                                                                        ^ Clear reserved bits
        emit AccessoryCreated(accessoryId, msg.sender, priceWei, totalSupply, name);
        AccessoriesByManager[msg.sender].add(accessoryId);
        return accessoryId;
    }

    /**
     * @dev Create an accessory with an eligible list
     */
    function createAccessory (uint8[3] calldata WHM, uint256 priceWei, uint16 totalSupply, bytes28 name, bytes2[4] calldata positions, bytes8[] calldata palettes, bytes calldata IDAT, bytes32[100] calldata eligibleList)
        public
        returns (uint256)
    {
        uint256 accessoryId = createAccessory(WHM, priceWei, totalSupply, name, positions, palettes, IDAT);
        AllEligibleLists[accessoryId] = eligibleList;
        MoonCatBitSet.activate(AllEligibleLists[accessoryId]);
        return accessoryId;
    }

    /**
     * @dev Add a color palette variant to an existing accessory
     */
    function addAccessoryPalette (uint256 accessoryId, bytes8 newPalette)
        public
        onlyAccessoryManager(accessoryId)
    {
        require(uint64(newPalette) != 0, "Invalid Palette");
        Accessory storage accessory = AllAccessories[accessoryId];
        bytes8[7] storage accessoryPalettes = accessory.palettes;

        require(uint64(accessoryPalettes[6]) == 0, "Palette Limit Exceeded");
        uint paletteIndex = 1;
        while(uint64(accessoryPalettes[paletteIndex]) > 0){
            paletteIndex++;
        }
        accessoryPalettes[paletteIndex] = newPalette;
    }

    /**
     * @dev Give ownership of an accessory to someone else
     */
    function transferAccessoryManagement (uint256 accessoryId, address payable newManager)
        public
        onlyAccessoryManager(accessoryId)
        notZeroAddress(newManager)
    {
        Accessory storage accessory = AllAccessories[accessoryId];
        AccessoriesByManager[accessory.manager].remove(accessoryId);
        AccessoriesByManager[newManager].add(accessoryId);
        accessory.manager = newManager;
        emit AccessoryManagementTransferred(accessoryId, newManager);
    }

    /**
     * @dev Set accessory to have a new price
     */
    function setAccessoryPrice (uint256 accessoryId, uint256 newPriceWei)
        public
        onlyAccessoryManager(accessoryId)
        validPrice(newPriceWei)
    {
        Accessory storage accessory = AllAccessories[accessoryId];

        if(accessory.price != newPriceWei){
            accessory.price = uint72(newPriceWei);
            emit AccessoryPriceChanged(accessoryId, newPriceWei);
        }
    }

    /**
     * @dev Set accessory eligible list
     */
    function setEligibleList (uint256 accessoryId, bytes32[100] calldata eligibleList)
        public
        onlyAccessoryManager(accessoryId)
    {
        AllEligibleLists[accessoryId] = eligibleList;
        MoonCatBitSet.activate(AllEligibleLists[accessoryId]);
        emit EligibleListSet(accessoryId);
    }

    /**
     * @dev Clear accessory eligible list
     */
    function clearEligibleList (uint256 accessoryId)
        public
        onlyAccessoryManager(accessoryId)
    {
        delete AllEligibleLists[accessoryId];
        emit EligibleListCleared(accessoryId);
    }

    /**
     * @dev Turns eligible list on or off without setting/clearing
     */
    function toggleEligibleList (uint256 accessoryId, bool active)
        public
        onlyAccessoryManager(accessoryId)
    {
        bool isActive = MoonCatBitSet.isActive(AllEligibleLists[accessoryId]);
        if(isActive && !active) {
            MoonCatBitSet.deactivate(AllEligibleLists[accessoryId]);
            emit EligibleListCleared(accessoryId);
        } else if (!isActive && active){
            MoonCatBitSet.activate(AllEligibleLists[accessoryId]);
            emit EligibleListSet(accessoryId);
        }
    }

    /**
     * @dev Add/Remove individual rescueOrders from an eligibleSet
     */
    function editEligibleMoonCats(uint256 accessoryId, bool targetState, uint16[] calldata rescueOrders)
        public
        onlyAccessoryManager(accessoryId)
    {
        bytes32[100] storage eligibleList = AllEligibleLists[accessoryId];
        for(uint i = 0; i < rescueOrders.length; i++){
            require(rescueOrders[i] < 25440, "Out of bounds");
            if(targetState) {
                MoonCatBitSet.setBit(eligibleList, rescueOrders[i]);
            } else {
                MoonCatBitSet.clearBit(eligibleList, rescueOrders[i]);
            }
        }
        if(MoonCatBitSet.isActive(eligibleList)){
            emit EligibleListSet(accessoryId);
        }
    }

    /**
     * @dev Buy an accessory as the manager of that accessory
     *
     * Accessory managers always get charged zero cost for buying/applying their own accessories,
     * and always bypass the EligibleList (if there is any).
     *
     * A purchase by the accessory manager still reduces the available supply of an accessory, and
     * the Manager must be the owner of or be granted access to the MoonCat to which the accessory
     * is being applied.
     */
    function managerApplyAccessory (uint256 rescueOrder, uint256 accessoryId, uint8 paletteIndex, uint16 zIndex)
        public
        onlyAccessoryManager(accessoryId)
        onlyAMCOwner(rescueOrder)
        returns (uint256)
    {
        require(AllAccessories[accessoryId].availableSupply > 0, "Supply Exhausted");
        AllAccessories[accessoryId].availableSupply--;
        return applyAccessory(rescueOrder, accessoryId, paletteIndex, zIndex);
    }

    /**
     * @dev Remove accessory from the market forever by transferring
     * management to the zero address, setting it as not for sale, and
     * setting the total supply to the current existing quantity.
     */
    function discontinueAccessory (uint256 accessoryId)
        public
        onlyAccessoryManager(accessoryId)
    {
        Accessory storage accessory = AllAccessories[accessoryId];
        accessory.price = NOT_FOR_SALE;
        AccessoriesByManager[accessory.manager].remove(accessoryId);
        AccessoriesByManager[address(0)].add(accessoryId);
        accessory.manager = payable(address(0));
        accessory.totalSupply = accessory.totalSupply - accessory.availableSupply;
        accessory.availableSupply = 0;
        emit AccessoryDiscontinued(accessoryId);
    }

    /* User */

    /**
     * @dev Purchase and apply an accessory in a standard manner.
     *
     * This method is an internal method for doing standard permission checks before calling the applyAccessory function.
     * This method checks that an accessory is set to be allowed for sale (not set to the max price), that there's enough supply left,
     * and that the buyer has supplied enough ETH to satisfy the price of the accessory.
     *
     * In addition, it checks to ensure that the MoonCat receiving the accessory is owned by the address making this purchase,
     * and that the MoonCat purchasing the accessory is on the Eligible List for that accessory.
     */
    function buyAndApplyAccessory (uint256 rescueOrder, uint256 accessoryId, uint8 paletteIndex, uint16 zIndex, address payable referrer)
        private
        onlyAMCOwner(rescueOrder)
        notZeroAddress(referrer)
        accessoryExists(accessoryId)
        returns (uint256)
    {
        require(isEligible(rescueOrder, accessoryId), "Ineligible");
        Accessory storage accessory = AllAccessories[accessoryId];
        require(accessory.price != NOT_FOR_SALE, "Not For Sale");
        require(accessory.availableSupply > 0, "Supply Exhausted");
        accessory.availableSupply--;
        require(address(this).balance >= accessory.price, "Insufficient Value");
        emit AccessoryPurchased(accessoryId, rescueOrder, accessory.price);
        uint256 ownedAccessoryId = applyAccessory(rescueOrder, accessoryId, paletteIndex, zIndex);
        if(accessory.price > 0) {
            sendPayment(accessory.manager, accessory.price, referrer);
        }
        return ownedAccessoryId;
    }

    /**
     * @dev Buy an accessory that is up for sale by its owner
     *
     * This method is the typical purchase method used by storefronts;
     * it allows the storefront to claim a referral fee for the purchase.
     *
     * Passing a z-index value of zero to this method just purchases the accessory,
     * but does not make it an active part of the MoonCat's appearance.
     */
    function buyAccessory (uint256 rescueOrder, uint256 accessoryId, uint8 paletteIndex, uint16 zIndex, address payable referrer)
        public
        payable
        returns (uint256)
    {
        uint256 ownedAccessoryId = buyAndApplyAccessory(rescueOrder, accessoryId, paletteIndex, zIndex, referrer);
        if(address(this).balance > 0){
            // The buyer over-paid; transfer their funds back to them
            payable(msg.sender).transfer(address(this).balance);
        }
        return ownedAccessoryId;
    }

    /**
     * @dev Buy an accessory that is up for sale by its owner
     *
     * This method is a generic fallback method if no referrer address is given for a purchase.
     * Defaults to the owner of the contract to receive the referral fee in this case.
     */
    function buyAccessory (uint256 rescueOrder, uint256 accessoryId, uint8 paletteIndex, uint16 zIndex)
        public
        payable
        returns (uint256)
    {
        return buyAccessory(rescueOrder, accessoryId, paletteIndex, zIndex, owner);
    }

    /**
     * @dev Buy multiple accessories at once; setting a palette and z-index for each one
     */
    function buyAccessories (AccessoryBatchData[] calldata orders, address payable referrer)
        public
        payable
    {
        for (uint256 i = 0; i < orders.length; i++) {
            AccessoryBatchData memory order = orders[i];
            buyAndApplyAccessory(order.rescueOrder, order.ownedIndexOrAccessoryId, order.paletteIndex, order.zIndex, referrer);
        }
        if(address(this).balance > 0){
            // The buyer over-paid; transfer their funds back to them
            payable(msg.sender).transfer(address(this).balance);
        }
    }

    /**
     * @dev Buy multiple accessories at once; setting a palette and z-index for each one (setting the contract owner as the referrer)
     */
    function buyAccessories (AccessoryBatchData[] calldata orders)
        public
        payable
    {
        buyAccessories(orders, owner);
    }

    /**
     * @dev Change the status of an owned accessory (worn or not, z-index ordering, color palette variant)
     */
    function alterAccessory (uint256 rescueOrder, uint256 ownedAccessoryIndex, uint8 paletteIndex, uint16 zIndex)
        public
        onlyAMCOwner(rescueOrder)
    {
        OwnedAccessory[] storage ownedAccessories = AccessoriesByMoonCat[rescueOrder];
        require(ownedAccessoryIndex < ownedAccessories.length, "Owned Accessory Not Found");
        OwnedAccessory storage ownedAccessory = ownedAccessories[ownedAccessoryIndex];
        require((paletteIndex <= 7) && (uint64(AllAccessories[ownedAccessory.accessoryId].palettes[paletteIndex]) != 0), "Palette Not Found");
        ownedAccessory.paletteIndex = paletteIndex;
        ownedAccessory.zIndex = zIndex;
        emit AccessoryApplied(ownedAccessory.accessoryId, rescueOrder, paletteIndex, zIndex);
    }

    /**
    * @dev Change the status of multiple accessories at once
    */
    function alterAccessories (AccessoryBatchData[] calldata alterations)
        public
    {
        for(uint i = 0; i < alterations.length; i++ ){
            AccessoryBatchData memory alteration = alterations[i];
            alterAccessory(alteration.rescueOrder, alteration.ownedIndexOrAccessoryId, alteration.paletteIndex, alteration.zIndex);
        }
    }

    /* View - Accessories */

    /**
     * @dev How many accessories exist in this contract?
     */
    function totalAccessories ()
        public
        view
        returns (uint256)
    {
        return AllAccessories.length;
    }

    /**
     * @dev Checks if there is an accessory with same IDAT data
     */
    function isAccessoryUnique(bytes calldata IDAT)
        public
        view
        returns (bool)
    {
        bytes32 accessoryHash = keccak256(IDAT);
        return (!accessoryHashes[accessoryHash]);
    }

    /**
     * @dev How many palettes are defined for an accessory?
     */
    function accessoryPaletteCount (uint256 accessoryId)
        public
        view
        accessoryExists(accessoryId)
        returns (uint8)
    {
        bytes8[7] memory accessoryPalettes = AllAccessories[accessoryId].palettes;
        for(uint8 i = 0; i < accessoryPalettes.length; i++) {
            if (uint64(accessoryPalettes[i]) == 0) {
                return i;
            }
        }
        return uint8(accessoryPalettes.length);
    }

    /**
     * @dev Fetch a specific palette for a given accessory
     */
    function accessoryPalette (uint256 accessoryId, uint256 paletteIndex)
        public
        view
        returns (bytes8)
    {
        return AllAccessories[accessoryId].palettes[paletteIndex];
    }

    /**
     * @dev Fetch data about a given accessory
     */
    function accessoryInfo (uint256 accessoryId)
        public
        view
        accessoryExists(accessoryId)
        returns (uint16 totalSupply, uint16 availableSupply, bytes28 name, address manager, uint8 metabyte, uint8 availablePalettes, bytes2[4] memory positions, bool availableForPurchase, uint256 price)
    {
        Accessory memory accessory = AllAccessories[accessoryId];
        availablePalettes = accessoryPaletteCount(accessoryId);
        bool available = accessory.price != NOT_FOR_SALE && accessory.availableSupply > 0;
        return (accessory.totalSupply, accessory.availableSupply, accessory.name, accessory.manager, accessory.meta, availablePalettes, accessory.positions, available, accessory.price);
    }

    /**
     * @dev Fetch image data about a given accessory
     */
    function accessoryImageData (uint256 accessoryId)
        public
        view
        accessoryExists(accessoryId)
        returns (bytes2[4] memory positions, bytes8[7] memory palettes, uint8 width, uint8 height, uint8 meta, bytes memory IDAT)
    {
        Accessory memory accessory = AllAccessories[accessoryId];
        return (accessory.positions, accessory.palettes, accessory.width, accessory.height, accessory.meta, accessory.IDAT);
    }

    /**
     * @dev Fetch EligibleList for a given accessory
     */
    function accessoryEligibleList(uint256 accessoryId)
        public
        view
        accessoryExists(accessoryId)
        returns (bytes32[100] memory)
    {
        return AllEligibleLists[accessoryId];
    }

    /*  View - Manager */

    /**
     * @dev Which address manages a specific accessory?
     */
    function managerOf (uint256 accessoryId)
        public
        view
        accessoryExists(accessoryId)
        returns (address)
    {
        return AllAccessories[accessoryId].manager;
    }

    /**
     * @dev How many accessories does a given address manage?
     */
    function balanceOf (address manager)
        public
        view
        returns (uint256)
    {
        return AccessoriesByManager[manager].length();
    }

    /**
     * @dev Iterate through a given address's managed accessories
     */
    function managedAccessoryByIndex (address manager, uint256 managedAccessoryIndex)
        public
        view
        returns (uint256)
    {
        return AccessoriesByManager[manager].at(managedAccessoryIndex);
    }

    /*  View - AcclimatedMoonCat */

    /**
     * @dev How many accessories does a given MoonCat own?
     */
    function balanceOf (uint256 rescueOrder)
        public
        view
        returns (uint256)
    {
        return AccessoriesByMoonCat[rescueOrder].length;
    }

    /**
     * @dev Iterate through a given MoonCat's accessories
     */
    function ownedAccessoryByIndex (uint256 rescueOrder, uint256 ownedAccessoryIndex)
        public
        view
        returns (OwnedAccessory memory)
    {
        require(ownedAccessoryIndex < AccessoriesByMoonCat[rescueOrder].length, "Index out of bounds");
        return AccessoriesByMoonCat[rescueOrder][ownedAccessoryIndex];
    }

    /**
     * @dev Lookup function to see if this MoonCat has already purchased a given accessory
     */
    function doesMoonCatOwnAccessory (uint256 rescueOrder, uint256 accessoryId)
        public
        view
        returns (bool)
    {
        return OwnedAccessoriesByMoonCat[rescueOrder][accessoryId];
    }

}

Read Contract

AccessoriesByMoonCat 0x3b0a6b7d → uint232, uint8, uint16
accessoryEligibleList 0xedfc47c8 → bytes32[100]
accessoryHashes 0xa36139d2 → bool
accessoryImageData 0xf9585a65 → bytes2[4], bytes8[7], uint8, uint8, uint8, bytes
accessoryInfo 0x0b7dd23a → uint16, uint16, bytes28, address, uint8, uint8, bytes2[4], bool, uint256
accessoryPalette 0x9c798a7d → bytes8
accessoryPaletteCount 0x4ebd2b77 → uint8
balanceOf 0x70a08231 → uint256
balanceOf 0x9cc7f708 → uint256
doesMoonCatOwnAccessory 0xa38097ea → bool
feeDenominator 0x180b0d7e → uint256
frozen 0x054f7d9c → bool
isAccessoryUnique 0x8789b8da → bool
isEligible 0xf09e82e2 → bool
managedAccessoryByIndex 0xaedd83fa → uint256
managerOf 0xd7fbee3d → address
ownedAccessoryByIndex 0x8e4aee06 → tuple
owner 0x8da5cb5b → address
referralDenominator 0x0cbc9527 → uint256
totalAccessories 0xe7718594 → uint256

Write Contract 29 functions

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

addAccessoryPalette 0xd5f62476
uint256 accessoryId
bytes8 newPalette
alterAccessories 0x07e43b2c
tuple[] alterations
alterAccessory 0x9beab624
uint256 rescueOrder
uint256 ownedAccessoryIndex
uint8 paletteIndex
uint16 zIndex
batchAndMetaByte 0x8d766718
uint8 value
uint256[] accessoryIds
batchOrMetaByte 0x7da94108
uint8 value
uint256[] accessoryIds
buyAccessories 0x5cf00565
tuple[] orders
address referrer
buyAccessories 0x53f40d40
tuple[] orders
buyAccessory 0x624d0fe2
uint256 rescueOrder
uint256 accessoryId
uint8 paletteIndex
uint16 zIndex
address referrer
returns: uint256
buyAccessory 0xe6c2cae6
uint256 rescueOrder
uint256 accessoryId
uint8 paletteIndex
uint16 zIndex
returns: uint256
clearEligibleList 0x721669d2
uint256 accessoryId
createAccessory 0x695f052b
uint8[3] WHM
uint256 priceWei
uint16 totalSupply
bytes28 name
bytes2[4] positions
bytes8[] palettes
bytes IDAT
bytes32[100] eligibleList
returns: uint256
createAccessory 0xb805f331
uint8[3] WHM
uint256 priceWei
uint16 totalSupply
bytes28 name
bytes2[4] positions
bytes8[] palettes
bytes IDAT
returns: uint256
discontinueAccessory 0xdd9eab0d
uint256 accessoryId
editEligibleMoonCats 0x30862bae
uint256 accessoryId
bool targetState
uint16[] rescueOrders
freeze 0x62a5af3b
No parameters
managerApplyAccessory 0x53855967
uint256 rescueOrder
uint256 accessoryId
uint8 paletteIndex
uint16 zIndex
returns: uint256
ownerCreateAccessory 0xa84ec3c6
address manager
uint8[3] WHM
uint256 priceWei
uint16 totalSupply
bytes28 name
bytes2[4] positions
bytes8[7] initialPalettes
bytes IDAT
bytes32[100] eligibleList
returns: uint256
ownerCreateAccessory 0xe3776a69
address manager
uint8[3] WHM
uint256 priceWei
uint16 totalSupply
bytes28 name
bytes2[4] positions
bytes8[7] initialPalettes
bytes IDAT
returns: uint256
setAccessoryPrice 0x47ef2b36
uint256 accessoryId
uint256 newPriceWei
setEligibleList 0xa477a7d3
uint256 accessoryId
bytes32[100] eligibleList
setFee 0x69fe0e2d
uint256 denominator
setMetaByte 0xf8d0070a
uint256 accessoryId
uint8 metabyte
setReferralFee 0x713494d7
uint256 denominator
toggleEligibleList 0x2940bc7a
uint256 accessoryId
bool active
transferAccessoryManagement 0x50c6d55f
uint256 accessoryId
address newManager
transferOwnership 0xf2fde38b
address newOwner
unfreeze 0x6a28f000
No parameters
withdrawForeignERC20 0x5c471995
address tokenContract
withdrawForeignERC721 0x0ce06b68
address tokenContract
uint256 tokenId

Recent Transactions

No transactions found for this address