Address Contract Partially Verified
Address
0xb8CDf9C4D795B18CD6748AF67258aDd526A8D56d
Balance
0 ETH
Nonce
1
Code Size
11983 bytes
Creator
0x49Bb38D0...9D0e at tx 0xc57a3eed...99a2da
Indexed Transactions
0
Contract Bytecode
11983 bytes
0x608060405234801561001057600080fd5b50600436106102275760003560e01c806378229c3611610130578063c4c39ed5116100b8578063e1d3cb551161007c578063e1d3cb5514610517578063e4a9209714610537578063e78d02801461054a578063ea2f29971461055d578063f2fde38b1461057057600080fd5b8063c4c39ed5146104ad578063c748668b146104c0578063c818c1ab146104c8578063d24f5232146104db578063dde44b891461050457600080fd5b80638da5cb5b116100ff5780638da5cb5b1461045a57806397a495f61461046b578063a886c3771461047e578063b422b78f14610487578063bd2f6eb81461049a57600080fd5b806378229c36146103e5578063821ba40e146103f857806382fa65621461040b578063898572a61461041e57600080fd5b80634b01c08b116101b35780635add59cb116101825780635add59cb1461038f5780635d6e05c1146103a357806361f64457146103b65780636a895e29146103ca578063715018a6146103dd57600080fd5b80634b01c08b146103375780634f3815d5146103405780635055fbc31461035357806354c856dc1461038657600080fd5b80631daebf56116101fa5780631daebf56146102d65780632709c7a1146102de57806335413f9b146102fe57806336222c68146103115780633c72f6b51461032457600080fd5b806308346d851461022c5780630ab9cf3a14610248578063146294cf1461025d578063150b7a021461029e575b600080fd5b610235600b5481565b6040519081526020015b60405180910390f35b61025b610256366004612887565b610583565b005b61028661026b3660046128a9565b6002602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161023f565b6102bd6102ac3660046128d7565b630a85bd0160e11b95945050505050565b6040516001600160e01b0319909116815260200161023f565b61025b6107d0565b6102356102ec366004612976565b600f6020526000908152604090205481565b61025b61030c3660046129a9565b6107f9565b61025b61031f366004612a67565b610867565b61025b610332366004612a67565b610c86565b610235600e5481565b61025b61034e3660046129a9565b610ebd565b6103766103613660046128a9565b60056020526000908152604090205460ff1681565b604051901515815260200161023f565b610235600d5481565b600a5461037690600160a81b900460ff1681565b61025b6103b1366004612976565b610f27565b600a5461037690600160a01b900460ff1681565b61025b6103d83660046129a9565b610f51565b61025b611155565b61025b6103f3366004612887565b611169565b61025b610406366004612a67565b6114cf565b600954610286906001600160a01b031681565b61044561042c3660046128a9565b6007602052600090815260409020805460019091015482565b6040805192835260208301919091520161023f565b6000546001600160a01b0316610286565b61025b610479366004612887565b6118d1565b610235600c5481565b600854610286906001600160a01b031681565b61025b6104a83660046128a9565b611c41565b61025b6104bb3660046128a9565b611c4e565b61025b611de3565b61025b6104d63660046129a9565b611e0c565b6102866104e93660046128a9565b6003602052600090815260409020546001600160a01b031681565b61025b6105123660046128a9565b611e76565b6102356105253660046128a9565b60066020526000908152604090205481565b61025b610545366004612a67565b611e83565b610235610558366004612aea565b612025565b61025b61056b366004612976565b612056565b61025b61057e366004612976565b612080565b6000828152600760209081526040808320805460019091015460095483516339c5c1a760e01b81529351929591946001600160a01b03909116936339c5c1a793600480830194919283900301908290875af11580156105e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060a9190612b16565b15156001146106585760405162461bcd60e51b81526020600482015260156024820152741c995d99585b081b9bdd081858dd1a5d99481e595d605a1b60448201526064015b60405180910390fd5b6000848152600360205260409020546001600160a01b03163314806106f057506009546040516331a9108f60e11b81526004810186905233916001600160a01b031690636352211e90602401602060405180830381865afa1580156106c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e59190612b38565b6001600160a01b0316145b61070c5760405162461bcd60e51b815260040161064f90612b55565b60008481526005602052604090205460ff161561075e5760405162461bcd60e51b815260206004820152601060248201526f185b1c9958591e4814995d99585b195960821b604482015260640161064f565b8183148061076b57508083145b6107a65760405162461bcd60e51b815260206004820152600c60248201526b77726f6e672063686f69636560a01b604482015260640161064f565b5050600091825260066020908152604080842092909255600590529020805460ff19166001179055565b6107d86120f6565b600a805460ff60a01b198116600160a01b9182900460ff1615909102179055565b600a54600160a01b900460ff166108225760405162461bcd60e51b815260040161064f90612b78565b60005b81518110156108635761085182828151811061084357610843612ba8565b602002602001015133612150565b8061085b81612bd4565b915050610825565b5050565b83838383600b54421061088c5760405162461bcd60e51b815260040161064f90612bed565b6108f582828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600c546040519092506108da915033908890602001612c18565b6040516020818303038152906040528051906020012061224b565b6109115760405162461bcd60e51b815260040161064f90612c31565b600d5484600e546109229190612c51565b11156109405760405162461bcd60e51b815260040161064f90612c69565b336000908152600f6020526040902054839061095d908690612c51565b111561097b5760405162461bcd60e51b815260040161064f90612ca0565b83600e600082825461098d9190612c51565b9091555050336000908152600f6020526040812080548692906109b1908490612c51565b909155506109c29050600289612cfb565b1580156109ce57508715155b610a1a5760405162461bcd60e51b815260206004820152601d60248201527f7175616e746974792073686f756c642062652061206d6f64756c6f2032000000604482015260640161064f565b6000610a2760028a612d0f565b905060005b81811015610c7a57600854604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015610a7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa29190612d23565b90506000600960009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610af9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1d9190612d23565b600854600a5460405163fabdd6f160e01b81529293506001600160a01b039182169263fabdd6f192610b56921690600290600401612c18565b600060405180830381600087803b158015610b7057600080fd5b505af1158015610b84573d6000803e3d6000fd5b50506009546040516324e03ce160e21b81526001600160a01b039091169250639380f3849150610bbb903390600190600401612c18565b600060405180830381600087803b158015610bd557600080fd5b505af1158015610be9573d6000803e3d6000fd5b505050506040518060400160405280838152602001836001610c0b9190612c51565b9052600082815260076020908152604090912082518155910151600191820155600080516020612e7a8339815191529033908490610c4a908290612c51565b8442604051610c5d959493929190612d3c565b60405180910390a150508080610c7290612bd4565b915050610a2c565b50505050505050505050565b83838383600b544210610cab5760405162461bcd60e51b815260040161064f90612bed565b610cf982828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600c546040519092506108da915033908890602001612c18565b610d155760405162461bcd60e51b815260040161064f90612c31565b600d5484600e54610d269190612c51565b1115610d445760405162461bcd60e51b815260040161064f90612c69565b336000908152600f60205260409020548390610d61908690612c51565b1115610d7f5760405162461bcd60e51b815260040161064f90612ca0565b83600e6000828254610d919190612c51565b9091555050336000908152600f602052604081208054869290610db5908490612c51565b9091555050600854604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa158015610e04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e289190612d23565b60085460405163fabdd6f160e01b81529192506001600160a01b03169063fabdd6f190610e5b9030908d90600401612c18565b600060405180830381600087803b158015610e7557600080fd5b505af1158015610e89573d6000803e3d6000fd5b5050505060005b89811015610c7a57610eab610ea58284612c51565b33612261565b80610eb581612bd4565b915050610e90565b600a54600160a01b900460ff16610ee65760405162461bcd60e51b815260040161064f90612b78565b60005b815181101561086357610f15828281518110610f0757610f07612ba8565b6020026020010151336122f1565b80610f1f81612bd4565b915050610ee9565b610f2f6120f6565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600160a01b900460ff16610f7a5760405162461bcd60e51b815260040161064f90612b78565b60005b81518110156110b0576000828281518110610f9a57610f9a612ba8565b602002602001015190506000600860009054906101000a90046001600160a01b03166001600160a01b031663baa51f86858581518110610fdc57610fdc612ba8565b60200260200101516040518263ffffffff1660e01b815260040161100291815260200190565b6020604051808303816000875af1158015611021573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110459190612b16565b9050801515600103611078573360009081526004602090815260408220805460018101825590835291200182905561109b565b61109b84848151811061108d5761108d612ba8565b60200260200101513361247c565b505080806110a890612bd4565b915050610f7d565b5033600090815260046020526040902054156111525760085433600081815260046020819052604091829020915163019199ad60e01b81526001600160a01b039094169363019199ad936111079392909101612d6a565b600060405180830381600087803b15801561112157600080fd5b505af1158015611135573d6000803e3d6000fd5b505033600090815260046020526040812061115293509150612855565b50565b61115d6120f6565b611167600061256b565b565b600a5482908290600160a81b900460ff166111965760405162461bcd60e51b815260040161064f90612b78565b6008546040516331a9108f60e11b81526004810184905233916001600160a01b031690636352211e90602401602060405180830381865afa1580156111df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112039190612b38565b6001600160a01b0316146112295760405162461bcd60e51b815260040161064f90612dc6565b6008546040516331a9108f60e11b81526004810183905233916001600160a01b031690636352211e90602401602060405180830381865afa158015611272573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112969190612b38565b6001600160a01b0316146112bc5760405162461bcd60e51b815260040161064f90612dc6565b600854600a546040516323b872dd60e01b81526001600160a01b03928316926323b872dd926112f5923392909116908990600401612df5565b600060405180830381600087803b15801561130f57600080fd5b505af1158015611323573d6000803e3d6000fd5b5050600854600a546040516323b872dd60e01b81526001600160a01b0392831694506323b872dd935061135e92339216908890600401612df5565b600060405180830381600087803b15801561137857600080fd5b505af115801561138c573d6000803e3d6000fd5b505050506000600960009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114099190612d23565b6009546040516324e03ce160e21b81529192506001600160a01b031690639380f3849061143d903390600190600401612c18565b600060405180830381600087803b15801561145757600080fd5b505af115801561146b573d6000803e3d6000fd5b505060408051808201825288815260208082018981526000878152600790925290839020915182555160019091015551600080516020612e7a83398151915292506114c0915033908890889086904290612d3c565b60405180910390a15050505050565b83838383600b5442106114f45760405162461bcd60e51b815260040161064f90612bed565b61154282828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600c546040519092506108da915033908890602001612c18565b61155e5760405162461bcd60e51b815260040161064f90612c31565b600d5484600e5461156f9190612c51565b111561158d5760405162461bcd60e51b815260040161064f90612c69565b336000908152600f602052604090205483906115aa908690612c51565b11156115c85760405162461bcd60e51b815260040161064f90612ca0565b83600e60008282546115da9190612c51565b9091555050336000908152600f6020526040812080548692906115fe908490612c51565b9091555061160f9050600289612cfb565b15801561161b57508715155b6116675760405162461bcd60e51b815260206004820152601d60248201527f7175616e746974792073686f756c642062652061206d6f64756c6f2032000000604482015260640161064f565b600061167460028a612d0f565b905060005b81811015610c7a57600854604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa1580156116cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ef9190612d23565b90506000600960009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611746573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176a9190612d23565b600854600a5460405163fabdd6f160e01b81529293506001600160a01b039182169263fabdd6f1926117a3921690600290600401612c18565b600060405180830381600087803b1580156117bd57600080fd5b505af11580156117d1573d6000803e3d6000fd5b50506009546040516324e03ce160e21b81526001600160a01b039091169250639380f3849150611808903090600190600401612c18565b600060405180830381600087803b15801561182257600080fd5b505af1158015611836573d6000803e3d6000fd5b5050505060405180604001604052808381526020018360016118589190612c51565b9052600082815260076020908152604090912082518155910151600191820155600080516020612e7a8339815191529033908490611897908290612c51565b84426040516118aa959493929190612d3c565b60405180910390a16118bc81336125bb565b505080806118c990612bd4565b915050611679565b600a5482908290600160a81b900460ff166118fe5760405162461bcd60e51b815260040161064f90612b78565b6008546040516331a9108f60e11b81526004810184905233916001600160a01b031690636352211e90602401602060405180830381865afa158015611947573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196b9190612b38565b6001600160a01b0316146119915760405162461bcd60e51b815260040161064f90612dc6565b6008546040516331a9108f60e11b81526004810183905233916001600160a01b031690636352211e90602401602060405180830381865afa1580156119da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fe9190612b38565b6001600160a01b031614611a245760405162461bcd60e51b815260040161064f90612dc6565b600854600a546040516323b872dd60e01b81526001600160a01b03928316926323b872dd92611a5d923392909116908990600401612df5565b600060405180830381600087803b158015611a7757600080fd5b505af1158015611a8b573d6000803e3d6000fd5b5050600854600a546040516323b872dd60e01b81526001600160a01b0392831694506323b872dd9350611ac692339216908890600401612df5565b600060405180830381600087803b158015611ae057600080fd5b505af1158015611af4573d6000803e3d6000fd5b505050506000600960009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b719190612d23565b6009546040516324e03ce160e21b81529192506001600160a01b031690639380f38490611ba5903090600190600401612c18565b600060405180830381600087803b158015611bbf57600080fd5b505af1158015611bd3573d6000803e3d6000fd5b505060408051808201825288815260208082018981526000878152600790925290839020915182555160019091015551600080516020612e7a8339815191529250611c28915033908890889086904290612d3c565b60405180910390a1611c3a81336125bb565b5050505050565b611c496120f6565b600b55565b611c566120f6565b600e548111611ca05760405162461bcd60e51b81526020600482015260166024820152751cdd5c1c1b1e481b5a5b9a5b5d5b481c995858da195960521b604482015260640161064f565b600860009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611cf3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d179190612d23565b600860009054906101000a90046001600160a01b03166001600160a01b03166332cb6b0c6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611d6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d909190612d23565b611d9a9190612e19565b811115611dde5760405162461bcd60e51b815260206004820152601260248201527113585e081cdd5c1c1b1e481c995858da195960721b604482015260640161064f565b600d55565b611deb6120f6565b600a805460ff60a81b198116600160a81b9182900460ff1615909102179055565b600a54600160a01b900460ff16611e355760405162461bcd60e51b815260040161064f90612b78565b60005b815181101561086357611e64828281518110611e5657611e56612ba8565b60200260200101513361264b565b80611e6e81612bd4565b915050611e38565b611e7e6120f6565b600c55565b83838383600b544210611ea85760405162461bcd60e51b815260040161064f90612bed565b611ef682828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600c546040519092506108da915033908890602001612c18565b611f125760405162461bcd60e51b815260040161064f90612c31565b600d5484600e54611f239190612c51565b1115611f415760405162461bcd60e51b815260040161064f90612c69565b336000908152600f60205260409020548390611f5e908690612c51565b1115611f7c5760405162461bcd60e51b815260040161064f90612ca0565b83600e6000828254611f8e9190612c51565b9091555050336000908152600f602052604081208054869290611fb2908490612c51565b909155505060085460405163fabdd6f160e01b81526001600160a01b039091169063fabdd6f190611fe99033908c90600401612c18565b600060405180830381600087803b15801561200357600080fd5b505af1158015612017573d6000803e3d6000fd5b505050505050505050505050565b6004602052816000526040600020818154811061204157600080fd5b90600052602060002001600091509150505481565b61205e6120f6565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6120886120f6565b6001600160a01b0381166120ed5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161064f565b6111528161256b565b6000546001600160a01b031633146111675760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161064f565b6000828152600360205260409020546001600160a01b038281169116146121895760405162461bcd60e51b815260040161064f90612b55565b6009546040516323b872dd60e01b81526001600160a01b03909116906323b872dd906121bd90309085908790600401612df5565b600060405180830381600087803b1580156121d757600080fd5b505af11580156121eb573d6000803e3d6000fd5b5050506000838152600360205260409081902080546001600160a01b0319169055517f85a4ac7589d168612b4018473a963c60421315d02eeb9ad728db7d818d477b5d915061223f90839085904290612e30565b60405180910390a15050565b60008261225885846127d6565b14949350505050565b6000828152600260205260409020546001600160a01b0316156122965760405162461bcd60e51b815260040161064f90612e51565b6000828152600260205260409081902080546001600160a01b0319166001600160a01b038416179055517fd5116130669483bb404f94eecc4c00b3fcecbbd962841e5c130f4becc5b3355f9061223f90839085904290612e30565b6008546040516331a9108f60e11b8152600481018490526001600160a01b03838116921690636352211e90602401602060405180830381865afa15801561233c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123609190612b38565b6001600160a01b0316146123865760405162461bcd60e51b815260040161064f90612b55565b6000828152600260205260409020546001600160a01b0316156123bb5760405162461bcd60e51b815260040161064f90612e51565b6008546040516323b872dd60e01b81526001600160a01b03909116906323b872dd906123ef90849030908790600401612df5565b600060405180830381600087803b15801561240957600080fd5b505af115801561241d573d6000803e3d6000fd5b5050506000838152600260205260409081902080546001600160a01b0319166001600160a01b038516179055517fd5116130669483bb404f94eecc4c00b3fcecbbd962841e5c130f4becc5b3355f915061223f90839085904290612e30565b6000828152600260205260409020546001600160a01b038281169116146124b55760405162461bcd60e51b815260040161064f90612b55565b6008546040516323b872dd60e01b81526001600160a01b03909116906323b872dd906124e990309085908790600401612df5565b600060405180830381600087803b15801561250357600080fd5b505af1158015612517573d6000803e3d6000fd5b5050506000838152600260205260409081902080546001600160a01b0319169055517f2e0aadfdcc1b375405c7f7e9c66f661756d90fe8a6fe4a0a182b77e45fc0886e915061223f90839085904290612e30565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000828152600360205260409020546001600160a01b0316156125f05760405162461bcd60e51b815260040161064f90612e51565b6000828152600360205260409081902080546001600160a01b0319166001600160a01b038416179055517fe71a1073082ff4f09b6b629f64fc0273be705be91a45916c2666d38ccbad4c0d9061223f90839085904290612e30565b6009546040516331a9108f60e11b8152600481018490526001600160a01b03838116921690636352211e90602401602060405180830381865afa158015612696573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ba9190612b38565b6001600160a01b0316146126e05760405162461bcd60e51b815260040161064f90612b55565b6000828152600360205260409020546001600160a01b0316156127155760405162461bcd60e51b815260040161064f90612e51565b6009546040516323b872dd60e01b81526001600160a01b03909116906323b872dd9061274990849030908790600401612df5565b600060405180830381600087803b15801561276357600080fd5b505af1158015612777573d6000803e3d6000fd5b5050506000838152600360205260409081902080546001600160a01b0319166001600160a01b038516179055517fe71a1073082ff4f09b6b629f64fc0273be705be91a45916c2666d38ccbad4c0d915061223f90839085904290612e30565b600081815b845181101561281b57612807828683815181106127fa576127fa612ba8565b6020026020010151612823565b91508061281381612bd4565b9150506127db565b509392505050565b600081831061283f57600082815260208490526040902061284e565b60008381526020839052604090205b9392505050565b508054600082559060005260206000209081019061115291905b80821115612883576000815560010161286f565b5090565b6000806040838503121561289a57600080fd5b50508035926020909101359150565b6000602082840312156128bb57600080fd5b5035919050565b6001600160a01b038116811461115257600080fd5b6000806000806000608086880312156128ef57600080fd5b85356128fa816128c2565b9450602086013561290a816128c2565b935060408601359250606086013567ffffffffffffffff8082111561292e57600080fd5b818801915088601f83011261294257600080fd5b81358181111561295157600080fd5b89602082850101111561296357600080fd5b9699959850939650602001949392505050565b60006020828403121561298857600080fd5b813561284e816128c2565b634e487b7160e01b600052604160045260246000fd5b600060208083850312156129bc57600080fd5b823567ffffffffffffffff808211156129d457600080fd5b818501915085601f8301126129e857600080fd5b8135818111156129fa576129fa612993565b8060051b604051601f19603f83011681018181108582111715612a1f57612a1f612993565b604052918252848201925083810185019188831115612a3d57600080fd5b938501935b82851015612a5b57843584529385019392850192612a42565b98975050505050505050565b60008060008060608587031215612a7d57600080fd5b8435935060208501359250604085013567ffffffffffffffff80821115612aa357600080fd5b818701915087601f830112612ab757600080fd5b813581811115612ac657600080fd5b8860208260051b8501011115612adb57600080fd5b95989497505060200194505050565b60008060408385031215612afd57600080fd5b8235612b08816128c2565b946020939093013593505050565b600060208284031215612b2857600080fd5b8151801515811461284e57600080fd5b600060208284031215612b4a57600080fd5b815161284e816128c2565b6020808252600990820152683737ba1037bbb732b960b91b604082015260600190565b602080825260169082015275436f6e7472616374206973206e6f742061637469766560501b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201612be657612be6612bbe565b5060010190565b602080825260119082015270233932b29036b4b73a1034b99037bb32b960791b604082015260600190565b6001600160a01b03929092168252602082015260400190565b60208082526006908201526510b83937b7b360d11b604082015260600190565b60008219821115612c6457612c64612bbe565b500190565b6020808252601b908201527f4d617820737570706c7920667265656d696e7420726561636865640000000000604082015260600190565b60208082526025908201527f4e6f7420616c6c6f77656420746f20667265656d696e742074686973207175616040820152646e7469747960d81b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b600082612d0a57612d0a612ce5565b500690565b600082612d1e57612d1e612ce5565b500490565b600060208284031215612d3557600080fd5b5051919050565b6001600160a01b03959095168552602085019390935260408401919091526060830152608082015260a00190565b6000604082016040835280855480835260608501915086600052602092508260002060005b82811015612dab57815484529284019260019182019101612d8f565b5050506001600160a01b039490941692019190915250919050565b6020808252601590820152742cb7ba9036bab9ba1037bbb7103a34329027232a1760591b604082015260600190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600082821015612e2b57612e2b612bbe565b500390565b6001600160a01b039390931683526020830191909152604082015260600190565b6020808252600e908201526d105b1c9958591e481cdd185ad95960921b60408201526060019056fe8f9b65c4201143c15e345350ae2fbcb591a753d71eb2a62b3f804db0d26c242ca2646970667358221220746e68aa58f6d0935fa4f5cd55bb0dcf9d8c6bf19e055b304d05609fda125b7b64736f6c634300080e0033
Verified Source Code Partial Match
Compiler: v0.8.14+commit.80d49f37
EVM: london
Optimization: Yes (200 runs)
OperatorContract.sol 1137 lines
// File: @openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// File: @openzeppelin/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// File: @openzeppelin/contracts/security/ReentrancyGuard.sol
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol
// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)
pragma solidity ^0.8.0;
/**
* @dev These functions deal with verification of Merkle Tree proofs.
*
* The proofs can be generated using the JavaScript library
* https://github.com/miguelmota/merkletreejs[merkletreejs].
* Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
*
* See `test/utils/cryptography/MerkleProof.test.js` for some examples.
*
* 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.
*/
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 proved to be a part of a Merkle tree defined by
* `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
*
* _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}
*
* _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 the sibling nodes in `proof`,
* consuming from one or the other at each step according to the instructions given by
* `proofFlags`.
*
* _Available since v4.7._
*/
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuild 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 totalHashes = proofFlags.length;
// Check proof validity.
require(leavesLen + proof.length - 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 for 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) {
return hashes[totalHashes - 1];
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
/**
* @dev Calldata version of {processMultiProof}
*
* _Available since v4.7._
*/
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuild 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 totalHashes = proofFlags.length;
// Check proof validity.
require(leavesLen + proof.length - 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 for 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) {
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)
}
}
}
// File: erc721a/contracts/IERC721A.sol
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs
pragma solidity ^0.8.4;
/**
* @dev Interface of ERC721A.
*/
interface IERC721A {
/**
* The caller must own the token or be an approved operator.
*/
error ApprovalCallerNotOwnerNorApproved();
/**
* The token does not exist.
*/
error ApprovalQueryForNonexistentToken();
/**
* Cannot query the balance for the zero address.
*/
error BalanceQueryForZeroAddress();
/**
* Cannot mint to the zero address.
*/
error MintToZeroAddress();
/**
* The quantity of tokens minted must be more than zero.
*/
error MintZeroQuantity();
/**
* The token does not exist.
*/
error OwnerQueryForNonexistentToken();
/**
* The caller must own the token or be an approved operator.
*/
error TransferCallerNotOwnerNorApproved();
/**
* The token must be owned by `from`.
*/
error TransferFromIncorrectOwner();
/**
* Cannot safely transfer to a contract that does not implement the
* ERC721Receiver interface.
*/
error TransferToNonERC721ReceiverImplementer();
/**
* Cannot transfer to the zero address.
*/
error TransferToZeroAddress();
/**
* The token does not exist.
*/
error URIQueryForNonexistentToken();
/**
* The `quantity` minted with ERC2309 exceeds the safety limit.
*/
error MintERC2309QuantityExceedsLimit();
/**
* The `extraData` cannot be set on an unintialized ownership slot.
*/
error OwnershipNotInitializedForExtraData();
// =============================================================
// STRUCTS
// =============================================================
struct TokenOwnership {
// The address of the owner.
address addr;
// Stores the start time of ownership with minimal overhead for tokenomics.
uint64 startTimestamp;
// Whether the token has been burned.
bool burned;
// Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
uint24 extraData;
}
// =============================================================
// TOKEN COUNTERS
// =============================================================
/**
* @dev Returns the total number of tokens in existence.
* Burned tokens will reduce the count.
* To get the total number of tokens minted, please see {_totalMinted}.
*/
function totalSupply() external view returns (uint256);
// =============================================================
// IERC165
// =============================================================
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
* to learn more about how these ids are created.
*
* This function call must use less than 30000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
// =============================================================
// IERC721
// =============================================================
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables
* (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in `owner`'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`,
* checking first that contract recipients are aware of the ERC721 protocol
* to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move
* this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement
* {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external payable;
/**
* @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external payable;
/**
* @dev Transfers `tokenId` from `from` to `to`.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom}
* whenever possible.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token
* by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external payable;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the
* zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external payable;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom}
* for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
// =============================================================
// IERC721Metadata
// =============================================================
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
// =============================================================
// IERC2309
// =============================================================
/**
* @dev Emitted when tokens in `fromTokenId` to `toTokenId`
* (inclusive) is transferred from `from` to `to`, as defined in the
* [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
*
* See {_mintERC2309} for more details.
*/
event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}
// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
// File: contracts/2_Owner.sol
pragma solidity ^0.8.14;
interface IX2 {
function mintByOperator(address _addressBuyer, uint _quantity) external ;
function ownerOf(uint tokenId) external view returns (address owner);
function totalSupply() external view returns (uint);
function revealActive() external returns(bool);
}
interface IX1 {
function mintBySaleContract(address _addressBuyer, uint _quantity) external ;
function ownerOf(uint tokenId) external view returns (address owner);
function totalSupply() external view returns (uint);
function MAX_SUPPLY() external returns (uint);
function unstakeNFT(uint[] memory tokenId, address _to) external;
function isStaked(uint) external returns(bool);
}
library StructLib {
struct Parent {
uint tokenId1;
uint tokenId2;
}
}
contract OperatorContract is Ownable, ReentrancyGuard {
event X1Staked(address owner, uint256 tokenId, uint256 timeframe);
event X1Unstaked(address owner, uint256 tokenId, uint256 timeframe);
event X2Staked(address owner, uint256 tokenId, uint256 timeframe);
event X2Unstaked(address owner, uint256 tokenId, uint256 timeframe);
event Merged(address owner, uint256 tokenId1, uint tokenId2, uint createdTokenId, uint256 timeframe);
mapping(uint => address) public X1Depositaries;
mapping(uint => address) public X2Depositaries;
mapping(address => uint[]) public tokenIdOldStaking;
// mapping to check if given id is revealed
mapping(uint => bool) public isRevealed;
// mapping to get the chosen parentID to attribute revealed metadata
mapping(uint => uint) public chosenMainTokenId;
mapping(uint => StructLib.Parent) public parents;
address public X1Address;
address public X2Address;
address burnAddress = 0x000000000000000000000000000000000000dEaD;
// activation
bool public isStakingActive;
bool public isMergeActive;
uint public freeMintLimit;
// free mint root
bytes32 public freeMintRoot;
// free mint supply
uint public maxSupplyFreeMint = 1500;
uint public countMintedByFreeMint;
// Mapping to follow the freemint used
mapping(address => uint) public freeMintsUsed;
modifier stakingIsActive() {
require(isStakingActive, "Contract is not active");
_;
}
modifier mergeCheck(uint256 _tokenId1,uint256 _tokenId2) {
require(isMergeActive, "Contract is not active");
require(IERC721A(X1Address).ownerOf(_tokenId1) == msg.sender, "You must own the NFT.");
require(IERC721A(X1Address).ownerOf(_tokenId2) == msg.sender, "You must own the NFT.");
_;
}
modifier freeMintCheck(uint _quantity, uint count, bytes32[] calldata proof){
require(block.timestamp < freeMintLimit, "Free mint is over");
require(MerkleProof.verify(proof, freeMintRoot, keccak256(abi.encode(msg.sender, count))), "!proof");
require(countMintedByFreeMint + _quantity <= maxSupplyFreeMint , 'Max supply freemint reached');
require(freeMintsUsed[msg.sender] + _quantity <= count, 'Not allowed to freemint this quantity');
countMintedByFreeMint += _quantity;
freeMintsUsed[msg.sender] += _quantity;
_;
}
constructor(address oxyaAddress_, address X2Address_) {
X1Address = oxyaAddress_;
X2Address = X2Address_;
}
/**
* @dev Merge 2 tokens in the X1 contract to get 1 X2 token
* @param _tokenId1 ids of token X1
* @param _tokenId2 ids of token X2
*/
function Merge(uint _tokenId1,uint _tokenId2) public mergeCheck(_tokenId1, _tokenId2) {
IERC721A(X1Address).transferFrom(msg.sender, burnAddress, _tokenId1);
IERC721A(X1Address).transferFrom(msg.sender, burnAddress, _tokenId2);
uint totalSupply = IX2(X2Address).totalSupply();
IX2(X2Address).mintByOperator(msg.sender, 1);
parents[totalSupply] = StructLib.Parent(
_tokenId1,
_tokenId2
);
emit Merged(msg.sender, _tokenId1, _tokenId2, totalSupply, block.timestamp);
}
/**
* @dev Merge 2 tokens in the X1 contract to get 1 X2 token and stake it in present operator contrat
* @param _tokenId1 ids of token X1
* @param _tokenId2 ids of token X2
*/
function MergeAndStake(uint256 _tokenId1, uint256 _tokenId2) public mergeCheck(_tokenId1, _tokenId2) {
IERC721A(X1Address).transferFrom(msg.sender, burnAddress, _tokenId1);
IERC721A(X1Address).transferFrom(msg.sender, burnAddress, _tokenId2);
uint totalSupply = IX2(X2Address).totalSupply();
IX2(X2Address).mintByOperator(address(this), 1);
parents[totalSupply] = StructLib.Parent(
_tokenId1,
_tokenId2
);
emit Merged(msg.sender, _tokenId1, _tokenId2, totalSupply, block.timestamp);
stakeFreeMintX2NFT(totalSupply, msg.sender);
}
/**
* @dev Function to mint freeMints X1
* @param _quantity quantity of token X1 to mint
* @param count maximum of authorized mint for the msg.sender
* @param proof merkle proof
*/
function freeMintX1(uint _quantity, uint count, bytes32[] calldata proof) external freeMintCheck(_quantity, count, proof) {
IX1(X1Address).mintBySaleContract(msg.sender, _quantity);
}
/**
* @dev Function to mint and stake freeMints X1
* @param _quantity quantity of token X1 to mint
* @param count maximum of authorized mint for the msg.sender
* @param proof merkle proof
*/
function freeMintX1Stake(uint _quantity, uint count, bytes32[] calldata proof) external freeMintCheck(_quantity, count, proof) {
uint totalSupply = IX1(X1Address).totalSupply();
IX1(X1Address).mintBySaleContract(address(this), _quantity);
for(uint i=0; i<_quantity; i++){
stakeFreeMintX1NFT(totalSupply + i, msg.sender);
}
}
/**
* @dev Function to mint X1 and merge into X2
* @param _quantity quantity of token X1 to mint
* @param count maximum of authorized mint for the msg.sender
* @param proof merkle proof
*/
function freeMintX2( uint _quantity, uint count, bytes32[] calldata proof) external freeMintCheck(_quantity, count, proof) {
require(_quantity % 2 == 0 && _quantity != 0 , "quantity should be a modulo 2");
uint allowableMints = _quantity/2;
for(uint i; i < allowableMints; i++ ){
uint totalSupplyX1 = IX1(X1Address).totalSupply();
uint totalSupplyX2 = IX2(X2Address).totalSupply();
IX1(X1Address).mintBySaleContract(burnAddress, 2);
IX2(X2Address).mintByOperator(msg.sender, 1);
parents[totalSupplyX2] = StructLib.Parent(
totalSupplyX1 ,
totalSupplyX1 + 1
);
emit Merged(msg.sender, totalSupplyX1 , totalSupplyX1 + 1, totalSupplyX2 , block.timestamp);
}
}
/**
* @dev Function to mint X1 and merge and stake into X2
* @param _quantity quantity of token X1 to mint
* @param count maximum of authorized mint for the msg.sender
* @param proof merkle proof
*/
function freeMintX2Stake(uint _quantity, uint count, bytes32[] calldata proof) external freeMintCheck(_quantity, count, proof){
require(_quantity % 2 == 0 && _quantity != 0 , "quantity should be a modulo 2");
uint allowableMints = _quantity/2;
for(uint i; i < allowableMints; i++ ){
uint totalSupplyX1 = IX1(X1Address).totalSupply();
uint totalSupplyX2 = IX2(X2Address).totalSupply();
IX1(X1Address).mintBySaleContract(burnAddress, 2);
IX2(X2Address).mintByOperator(address(this), 1);
parents[totalSupplyX2] = StructLib.Parent(
totalSupplyX1,
totalSupplyX1 + 1
);
emit Merged(msg.sender, totalSupplyX1, totalSupplyX1 + 1, totalSupplyX2, block.timestamp);
stakeFreeMintX2NFT(totalSupplyX2, msg.sender);
}
}
//STAKING X2 NFT
/**
* @dev stake tokens X2 in the contract
* @param _tokenId ids of token
* @param _to address of staker
*/
function stakeX2NFT(uint256 _tokenId, address _to) internal {
require(IX2(X2Address).ownerOf(_tokenId) == _to, "not owner");
require(X2Depositaries[_tokenId] == address(0), "Already staked");
IERC721A(X2Address).transferFrom(_to, address(this), _tokenId);
X2Depositaries[_tokenId] = _to;
emit X2Staked(_to, _tokenId, block.timestamp);
}
/**
* @dev stake tokens X2 in the contract, called by freeMint function
* @param _tokenId ids of token
* @param _to address of staker
*/
function stakeFreeMintX2NFT(uint256 _tokenId, address _to) internal {
require(X2Depositaries[_tokenId] == address(0), "Already staked");
X2Depositaries[_tokenId] = _to;
emit X2Staked(_to, _tokenId, block.timestamp);
}
/**
* @dev stake multiple tokens X2 in the contract
* @param _tokenIds ids of tokens
*/
function batchStakeX2NFT(uint256[] memory _tokenIds) public stakingIsActive {
for (uint256 i = 0; i < _tokenIds.length; i++) {
stakeX2NFT(_tokenIds[i], msg.sender);
}
}
/**
* @dev unstake token X2 out of the contract
* @param _tokenId tokenId of token to unstake
* @param _to address of unstaker
*/
function unstakeX2NFT(uint256 _tokenId, address _to) internal {
require(X2Depositaries[_tokenId] == _to, "not owner");
IERC721A(X2Address).transferFrom(address(this), _to, _tokenId);
X2Depositaries[_tokenId] = address(0);
emit X2Unstaked(_to, _tokenId, block.timestamp);
}
/**
* @dev unstake multiple token X2 out of the contract
* @param _tokenIds tokenId of token to unstake
*/
function batchUnstakeX2NFT(uint256[] memory _tokenIds) public stakingIsActive {
for (uint256 i = 0; i < _tokenIds.length; i++) {
unstakeX2NFT(_tokenIds[i], msg.sender);
}
}
// STAKING X1 NFT
/**
* @dev stake tokens X1 in the contract
* @param _tokenId ids of token
* @param _to address of staker
*/
function stakeX1NFT(uint256 _tokenId, address _to) internal {
require(IX1(X1Address).ownerOf(_tokenId) == _to, "not owner");
require(X1Depositaries[_tokenId] == address(0), "Already staked");
IERC721A(X1Address).transferFrom(_to, address(this), _tokenId);
X1Depositaries[_tokenId] = _to;
emit X1Staked(_to, _tokenId, block.timestamp);
}
/**
* @dev stake tokens X1 in the contract, callable by freeMint
* @param _tokenId ids of token
* @param _to address of staker
*/
function stakeFreeMintX1NFT(uint256 _tokenId, address _to) internal {
require(X1Depositaries[_tokenId] == address(0), "Already staked");
X1Depositaries[_tokenId] = _to;
emit X1Staked(_to, _tokenId, block.timestamp);
}
/**
* @dev stake multiple tokens X1 in the contract
* @param _tokenIds ids of token
*/
function batchStakeX1NFT(uint256[] memory _tokenIds) public stakingIsActive {
for (uint256 i = 0; i < _tokenIds.length; i++) {
stakeX1NFT(_tokenIds[i], msg.sender);
}
}
// UNSTAKE X1 NFT
/**
* @dev unstake token X1 out of the contract
* @param _tokenId tokenId of token to unstake
* @param _to address of unstaker
*/
function unstakeX1NFT(uint256 _tokenId, address _to) internal {
require(X1Depositaries[_tokenId] == _to, "not owner");
IERC721A(X1Address).transferFrom(address(this), _to, _tokenId);
X1Depositaries[_tokenId] = address(0);
emit X1Unstaked(_to, _tokenId, block.timestamp);
}
/**
* @dev unstake token X1 out of the contract, also check the staking in previous contract
* @param _tokenIds tokenIds of token to unstake
*/
function batchUnstakeX1NFT(uint256[] memory _tokenIds) public stakingIsActive {
for (uint256 i = 0; i < _tokenIds.length; i++) {
uint256 value = _tokenIds[i];
bool isStakedInX1 = IX1(X1Address).isStaked(_tokenIds[i]);
if(isStakedInX1 == true){
tokenIdOldStaking[msg.sender].push(value);
} else {
unstakeX1NFT(_tokenIds[i], msg.sender);
}
}
if(tokenIdOldStaking[msg.sender].length > 0){
IX1(X1Address).unstakeNFT(tokenIdOldStaking[msg.sender], msg.sender);
delete tokenIdOldStaking[msg.sender];
}
}
/**
* @dev reveal selected NFT with the parent choice for the metadata
* @param _tokenId id of token to reveal
* @param parentChoice id of token Parent for metadata attribution
*/
function revealNFT(uint _tokenId, uint parentChoice ) public {
uint idParent1 = parents[_tokenId].tokenId1;
uint idParent2 =parents[_tokenId].tokenId2;
require(IX2(X2Address).revealActive() == true, "reveal not active yet");
require(X2Depositaries[_tokenId] == msg.sender || IX2(X2Address).ownerOf(_tokenId) == msg.sender , "not owner");
require(isRevealed[_tokenId] == false, "already Revealed");
require(parentChoice == idParent1 || parentChoice == idParent2, "wrong choice" );
chosenMainTokenId[_tokenId] = parentChoice;
isRevealed[_tokenId] = true;
}
/**
* @dev necessary to transfer tokens
*/
function onERC721Received(
address,
address,
uint256,
bytes calldata
) external pure returns (bytes4) {
return IERC721Receiver.onERC721Received.selector;
}
/**
* @dev necessary to calculate proof
* @param _root root for free mint
*/
function setFreeMintMerkleRoot(bytes32 _root) public onlyOwner {
freeMintRoot = _root;
}
/**
* @dev timestamp to activate freeMint
* @param timestamp timestamp limit for freemint
*/
function setFreeMintLimit(uint timestamp) external onlyOwner {
freeMintLimit = timestamp;
}
function setIsMergeActive() external onlyOwner {
isMergeActive = !isMergeActive;
}
function setIsStakingActive() external onlyOwner {
isStakingActive = !isStakingActive;
}
/*
* FreeMint supply
* function to change FreeMintSupply
*/
function setFreeMintSupply(uint _newFreeMintSupply) external onlyOwner {
require(_newFreeMintSupply > countMintedByFreeMint, "supply minimum reached");
require(_newFreeMintSupply <= IX1(X1Address).MAX_SUPPLY() - IX1(X1Address).totalSupply(), "Max supply reached");
maxSupplyFreeMint = _newFreeMintSupply;
}
// MIGRATION ONLY.
function setX1Contract(address X1Contract) public onlyOwner {
X1Address = X1Contract;
}
function setX2Contract(address X2Contract) public onlyOwner {
X2Address = X2Contract;
}
}
Read Contract
X1Address 0xb422b78f → address
X1Depositaries 0x146294cf → address
X2Address 0x82fa6562 → address
X2Depositaries 0xd24f5232 → address
chosenMainTokenId 0xe1d3cb55 → uint256
countMintedByFreeMint 0x4b01c08b → uint256
freeMintLimit 0x08346d85 → uint256
freeMintRoot 0xa886c377 → bytes32
freeMintsUsed 0x2709c7a1 → uint256
isMergeActive 0x5add59cb → bool
isRevealed 0x5055fbc3 → bool
isStakingActive 0x61f64457 → bool
maxSupplyFreeMint 0x54c856dc → uint256
onERC721Received 0x150b7a02 → bytes4
owner 0x8da5cb5b → address
parents 0x898572a6 → uint256, uint256
tokenIdOldStaking 0xe78d0280 → uint256
Write Contract 20 functions
These functions modify contract state and require a wallet transaction to execute.
Merge 0x78229c36
uint256 _tokenId1
uint256 _tokenId2
MergeAndStake 0x97a495f6
uint256 _tokenId1
uint256 _tokenId2
batchStakeX1NFT 0x4f3815d5
uint256[] _tokenIds
batchStakeX2NFT 0xc818c1ab
uint256[] _tokenIds
batchUnstakeX1NFT 0x6a895e29
uint256[] _tokenIds
batchUnstakeX2NFT 0x35413f9b
uint256[] _tokenIds
freeMintX1 0xe4a92097
uint256 _quantity
uint256 count
bytes32[] proof
freeMintX1Stake 0x3c72f6b5
uint256 _quantity
uint256 count
bytes32[] proof
freeMintX2 0x36222c68
uint256 _quantity
uint256 count
bytes32[] proof
freeMintX2Stake 0x821ba40e
uint256 _quantity
uint256 count
bytes32[] proof
renounceOwnership 0x715018a6
No parameters
revealNFT 0x0ab9cf3a
uint256 _tokenId
uint256 parentChoice
setFreeMintLimit 0xbd2f6eb8
uint256 timestamp
setFreeMintMerkleRoot 0xdde44b89
bytes32 _root
setFreeMintSupply 0xc4c39ed5
uint256 _newFreeMintSupply
setIsMergeActive 0xc748668b
No parameters
setIsStakingActive 0x1daebf56
No parameters
setX1Contract 0x5d6e05c1
address X1Contract
setX2Contract 0xea2f2997
address X2Contract
transferOwnership 0xf2fde38b
address newOwner
Recent Transactions
No transactions found for this address