Address Contract Verified
Address
0xb495A6312400938ae89EE88D1d2D0CfC18Ffe120
Balance
0.215047 ETH ($424.23)
Nonce
1
Code Size
17778 bytes
Creator
0x66FAb211...1c03 at tx 0x8ee9f3fe...d8818b
Indexed Transactions
0
Contract Bytecode
17778 bytes
0x60806040526004361061036f5760003560e01c8063a0c8883a116101c6578063d37a6cc9116100f7578063eddbc0e511610095578063f32bb4231161006f578063f32bb42314610a83578063f355eff014610aa5578063f5dabbef14610abb578063ff0f7b0f14610ad057600080fd5b8063eddbc0e514610a39578063f13da00514610a4e578063f2e0bf5014610a6e57600080fd5b8063e3a6bcd5116100d1578063e3a6bcd5146109e5578063e3d258a5146109fa578063e4109e4d14610a0f578063e9c07b4214610a2457600080fd5b8063d37a6cc914610970578063d6796d9814610986578063dc9ce7a5146109b857600080fd5b8063be9a655511610164578063c20741b61161013e578063c20741b614610910578063c2169da214610925578063c4a9e8721461093a578063c79bdb461461095057600080fd5b8063be9a6555146108c5578063c06ee0ad146108da578063c0e4727c146108fa57600080fd5b8063a8972909116101a0578063a89729091461085a578063aeee9b5b1461087a578063b4976dd114610890578063be22a03e146108b057600080fd5b8063a0c8883a14610805578063a24a29d714610825578063a2cb1be21461083a57600080fd5b80634dcc33a3116102a0578063785e9e861161023e5780638da5cb5b116102185780638da5cb5b1461076657806391cca3db146107845780639c3f5a83146107b85780639ddf9351146107d857600080fd5b8063785e9e861461071a5780638253b8e21461073a578063839fe7761461075057600080fd5b8063544736e61161027a578063544736e6146106a55780635beafaf3146106cf57806364148ec8146106ef578063755906951461070557600080fd5b80634dcc33a3146106385780634e9ac20814610658578063537c9d801461068557600080fd5b806338d0c2e81161030d5780633f64a7ab116102e75780633f64a7ab146105bf578063450ca5b5146105d457806345b4a7e71461060c57806348fe494e1461062257600080fd5b806338d0c2e8146105755780633baa9ad31461058a5780633d8c4f7d1461059f57600080fd5b80632ba677e2116103495780632ba677e2146104e557806332845545146104fa578063379e29191461053557806338bf3cfa1461055557600080fd5b80630962ef791461046f5780630e1d8d3e1461048f578063261b8fb2146104b857600080fd5b3661046a5760006064600e54346103869190614026565b6103909190614053565b905060007f000000000000000000000000b156ce9f20cf88a57b5e71f5ec8c1e2cb6e1f5936001600160a01b03168260405160006040518083038185875af1925050503d80600081146103ff576040519150601f19603f3d011682016040523d82523d6000602084013e610404565b606091505b50509050806104685760405162461bcd60e51b815260206004820152602560248201527f73656e7420666565206572726f723a20646576206574686572206973206e6f74604482015264081cd95b9d60da1b60648201526084015b60405180910390fd5b005b600080fd5b34801561047b57600080fd5b5061046861048a366004614067565b610af0565b34801561049b57600080fd5b506104a560035481565b6040519081526020015b60405180910390f35b3480156104c457600080fd5b506104d86104d3366004614067565b610c72565b6040516104af9190614118565b3480156104f157600080fd5b506104a5603c81565b34801561050657600080fd5b5061051a61051536600461413e565b610d2e565b604080519384526020840192909252908201526060016104af565b34801561054157600080fd5b50610468610550366004614067565b61109d565b34801561056157600080fd5b5061046861057036600461416a565b6110da565b34801561058157600080fd5b50610468611126565b34801561059657600080fd5b506104a5611140565b3480156105ab57600080fd5b506104686105ba366004614185565b611230565b3480156105cb57600080fd5b50600e546104a5565b3480156105e057600080fd5b50600b546105f4906001600160a01b031681565b6040516001600160a01b0390911681526020016104af565b34801561061857600080fd5b506104a560075481565b34801561062e57600080fd5b506104a560095481565b34801561064457600080fd5b506104a5610653366004614067565b61127e565b34801561066457600080fd5b506106786106733660046141af565b61133c565b6040516104af91906141d9565b34801561069157600080fd5b506104686106a03660046141fa565b611393565b3480156106b157600080fd5b50600d546106bf9060ff1681565b60405190151581526020016104af565b3480156106db57600080fd5b506104d86106ea36600461421c565b6113f4565b3480156106fb57600080fd5b506104a560015481565b34801561071157600080fd5b506104a5611405565b34801561072657600080fd5b50600a546105f4906001600160a01b031681565b34801561074657600080fd5b506104a560045481565b34801561075c57600080fd5b506104a5610e1081565b34801561077257600080fd5b506000546001600160a01b03166105f4565b34801561079057600080fd5b506105f47f000000000000000000000000b156ce9f20cf88a57b5e71f5ec8c1e2cb6e1f59381565b3480156107c457600080fd5b506104686107d3366004614067565b61144a565b3480156107e457600080fd5b506107f86107f336600461416a565b6115ee565b6040516104af919061423f565b34801561081157600080fd5b506106bf610820366004614067565b6117c0565b34801561083157600080fd5b506104a56118b7565b34801561084657600080fd5b50610468610855366004614067565b61193c565b34801561086657600080fd5b5061046861087536600461421c565b611978565b34801561088657600080fd5b506104a560065481565b34801561089c57600080fd5b506104686108ab3660046141fa565b611995565b3480156108bc57600080fd5b506104a56119f6565b3480156108d157600080fd5b50610468611a62565b3480156108e657600080fd5b506104686108f53660046141fa565b611b06565b34801561090657600080fd5b506104a560025481565b34801561091c57600080fd5b506104a5611f60565b34801561093157600080fd5b506104a5611f74565b34801561094657600080fd5b506104a5600c5481565b34801561095c57600080fd5b5061046861096b3660046141fa565b61205e565b34801561097c57600080fd5b506104a560085481565b34801561099257600080fd5b506109a66109a1366004614067565b6120d5565b60405160ff90911681526020016104af565b3480156109c457600080fd5b506109d86109d3366004614067565b612133565b6040516104af9190614346565b3480156109f157600080fd5b506104a5612202565b348015610a0657600080fd5b506104a5612210565b348015610a1b57600080fd5b506109a6600481565b348015610a3057600080fd5b506109a661227d565b348015610a4557600080fd5b506104a56122c6565b348015610a5a57600080fd5b5061051a610a693660046141fa565b6123b0565b348015610a7a57600080fd5b50610468611136565b348015610a8f57600080fd5b50610a986125dd565b6040516104af9190614355565b348015610ab157600080fd5b506104a560055481565b348015610ac757600080fd5b506104a5612715565b348015610adc57600080fd5b506106bf610aeb36600461421c565b612779565b600080610afc83612831565b91509150610b0a82826128bd565b336000908152604d60205260408120610b24600184614393565b60ff1660048110610b3757610b376143ac565b600302019050610c1281604051806060016040529081600082015481526020016001820154815260200160028201548152505084604051806101e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e82015481525050612ac3565b610c5e5760405162461bcd60e51b815260206004820152601960248201527f63616e206e6f7420636c61696d20726577617264732079657400000000000000604482015260640161045f565b610c69338285612b06565b50505050505050565b610c7a613ee7565b610c8382612ff6565b604080516101e08101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e082015260088201546101008201526009820154610120820152600a820154610140820152600b820154610160820152600c820154610180820152600d8201546101a0820152600e909101546101c082015292915050565b6000806000806000610d3f87612831565b6001600160a01b0388166000908152604d6020526040812092945090925090610d69600184614393565b60ff1660048110610d7c57610d7c6143ac565b6003020160405180606001604052908160008201548152602001600182015481526020016002820154815250509050610e5683604051806101e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e82015481525050613001565b816040015103610e73576000806000955095509550505050611096565b602080820151604080516101e081018252865481526001870154938101939093526002860154908301526003850154606083015260048501546080830152600585015460a0830152600685015460c0830152600785015460e083015260088501546101008301526009850154610120830152600a850154610140830152600b850154610160830152600c850154610180830152600d8501546101a0830152600e8501546101c0830152610f269190613022565b602080830151604080516101e081018252875481526001880154938101939093526002870154908301526003860154606083015260048601546080830152600586015460a0830152600686015460c0830152600786015460e083015260088601546101008301526009860154610120830152600a860154610140830152600b860154610160830152600c860154610180830152600d8601546101a0830152600e8601546101c0830152919750610fdb91613089565b602080830151604080516101e081018252875481526001880154938101939093526002870154908301526003860154606083015260048601546080830152600586015460a0830152600686015460c0830152600786015460e083015260088601546101008301526009860154610120830152600a860154610140830152600b860154610160830152600c860154610180830152600d8601546101a0830152600e8601546101c0830152919650611090916130d4565b93505050505b9250925092565b6000546001600160a01b031633146110c75760405162461bcd60e51b815260040161045f906143c2565b60328111156110d557600080fd5b600e55565b6000546001600160a01b031633146111045760405162461bcd60e51b815260040161045f906143c2565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b61112e61311f565b61113661316b565b61113e6131a4565b565b60008060005b600460ff8216101561122a5761121660118260ff166004811061116b5761116b6143ac565b600f0201604051806101e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e820154815250506131d3565b61122090836143f9565b9150600101611146565b50919050565b600f546001600160a01b0316331461124757600080fd5b600f80546001600160a01b0319908116909155600a80546001600160a01b03948516908316179055600b8054929093169116179055565b600061133661128c83612ff6565b604080516101e08101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e082015260088201546101008201526009820154610120820152600a820154610140820152600b820154610160820152600c820154610180820152600d8201546101a0820152600e909101546101c0820152613001565b92915050565b61136060405180606001604052806000815260200160008152602001600081525090565b61136a838361320e565b604080516060810182528254815260018301546020820152600290920154908201529392505050565b6000546001600160a01b031633146113bd5760405162461bcd60e51b815260040161045f906143c2565b6000821180156113cd5750808211155b6113e95760405162461bcd60e51b815260040161045f9061440c565b600591909155600655565b6113fc613ee7565b610c83826132fd565b60008060005b600460ff8216101561122a5760118160ff166004811061142d5761142d6143ac565b600f0201600801548261144091906143f9565b915060010161140b565b60008061145683612831565b9150915061146482826128bd565b6000611470338561320e565b80549091506114915760405162461bcd60e51b815260040161045f90614431565b600a54600182015460405163a9059cbb60e01b815233600482015260248101919091526001600160a01b039091169063a9059cbb906044016020604051808303816000875af11580156114e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061150c9190614472565b50826008016000815461151e90614494565b909155506001810154600984015410156115845760405162461bcd60e51b815260206004820152602160248201527f696e636f6e73697374656e7420706c616e65742f6163636f756e74207374616b6044820152606560f81b606482015260840161045f565b806001015483600901600082825461159c91906144ab565b9091555050336000908152604d602052604090206115bb600184614393565b60ff16600481106115ce576115ce6143ac565b600060039190910291909101818155600181018290556002015550505050565b60408051600480825260a0820190925260609160009190816020015b61162e60405180606001604052806000815260200160008152602001600081525090565b81526020019060019003908161160a57905050905060005b600460ff821610156117b9576001600160a01b0384166000908152604d6020526040812060ff83166004811061167e5761167e6143ac565b600302019050600060118360ff166004811061169c5761169c6143ac565b600f0201604051806101e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e82015481525050905061174d81613387565b6117585750506117b1565b80518254146117685750506117b1565b6040805160608101825283548152600184015460208201526002840154918101919091528451859060ff86169081106117a3576117a36143ac565b602002602001018190525050505b600101611646565b5092915050565b6000806117cc836120d5565b90508060ff166000036117e25750600092915050565b6118b060116117f2600184614393565b60ff1660048110611805576118056143ac565b600f0201604051806101e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e82015481525050613387565b9392505050565b60006118c16119f6565b600a546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611909573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192d91906144be565b61193791906144ab565b905090565b6000546001600160a01b031633146119665760405162461bcd60e51b815260040161045f906143c2565b6001811161197357600080fd5b600955565b61198a611984826132fd565b826133ab565b6119926131a4565b50565b6000546001600160a01b031633146119bf5760405162461bcd60e51b815260040161045f906143c2565b6000821180156119cf5750808211155b6119eb5760405162461bcd60e51b815260040161045f9061440c565b600791909155600855565b60008060005b600460ff8216101561122a5760118160ff1660048110611a1e57611a1e6143ac565b600f02016009015460118260ff1660048110611a3c57611a3c6143ac565b600f020160060154611a4e91906143f9565b611a5890836143f9565b91506001016119fc565b6000546001600160a01b03163314611a8c5760405162461bcd60e51b815260040161045f906143c2565b600d5460ff1615611ad15760405162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e481cdd185c9d1959608a1b604482015260640161045f565b600d805460ff191660019081179091555b600260ff82161161199257611af6816133c7565b611aff816144d7565b9050611ae2565b600d5460ff16611b465760405162461bcd60e51b815260206004820152600b60248201526a1b9bdd081cdd185c9d195960aa1b604482015260640161045f565b611b4e61311f565b611b57826117c0565b611b9a5760405162461bcd60e51b8152602060048201526014602482015273706c616e6574206973206e6f742065786973747360601b604482015260640161045f565b600080611ba684612831565b91509150611bb482826133ab565b611bbc6131a4565b604080516101e08101825283548152600184015460208201526002840154918101919091526003830154606082015260048301546080820152600583015460a0820152600683015460c0820152600783015460e082015260088301546101008201526009830154610120820152600a830154610140820152600b830154610160820152600c830154610180820152600d8301546101a0820152600e8301546101c0820152611c6990613387565b611cac5760405162461bcd60e51b8152602060048201526014602482015273706c616e6574206973206e6f742065786973747360601b604482015260640161045f565b600a546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611cf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d1991906144be565b600a546040516323b872dd60e01b8152336004820152306024820152604481018790529192506001600160a01b0316906323b872dd906064016020604051808303816000875af1158015611d71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d959190614472565b50600a546040516370a0823160e01b815230600482015260009183916001600160a01b03909116906370a0823190602401602060405180830381865afa158015611de3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0791906144be565b611e1191906144ab565b336000908152604d6020526040812091925090611e2f600186614393565b60ff1660048110611e4257611e426143ac565b6003020190508460000154816000015414611e6d578460080160008154611e68906144f6565b909155505b8454808255604080516101e081018252918252600187015460208301526002870154908201526003860154606082015260048601546080820152600586015460a0820152600686015460c0820152600786015460e082015260088601546101008201526009860154610120820152600a860154610140820152600b860154610160820152600c860154610180820152600d8601546101a0820152600e8601546101c0820152611f1b90613001565b816002018190555081816001016000828254611f3791906143f9565b9250508190555081856009016000828254611f5291906143f9565b909155505050505050505050565b6000611f6a611f74565b61193790476144ab565b60008060005b600460ff8216101561122a5761204a60118260ff1660048110611f9f57611f9f6143ac565b600f0201604051806101e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e82015481525050613455565b61205490836143f9565b9150600101611f7a565b6000546001600160a01b031633146120885760405162461bcd60e51b815260040161045f906143c2565b808211156120a85760405162461bcd60e51b815260040161045f9061440c565b6103e88111156120ca5760405162461bcd60e51b815260040161045f9061440c565b600191909155600255565b6000816000036120e757506000919050565b60005b600460ff8216101561212a578260118260ff166004811061210d5761210d6143ac565b600f02015403612122576118b081600161450f565b6001016120ea565b50600092915050565b61213b613f5d565b60008061214784612831565b604080516101e08101825283548152600184015460208201526002840154918101919091526003830154606082015260048301546080820152600583015460a0820152600683015460c0820152600783015460e082015260088301546101008201526009830154610120820152600a830154610140820152600b830154610160820152600c830154610180820152600d8301546101a0820152600e8301546101c082015291935091506121fa9082613474565b949350505050565b600061220c6122c6565b61192d5b600b546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612259573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193791906144be565b60008060005b600460ff8216101561122a57600060118260ff16600481106122a7576122a76143ac565b600f02015411156122be576122bb826144d7565b91505b600101612283565b60008060005b600460ff8216101561122a5761239c60118260ff16600481106122f1576122f16143ac565b600f0201604051806101e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e82015481525050613548565b6123a690836143f9565b91506001016122cc565b6000806000806123bf86612831565b50604080516101e08101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e082015260088201546101008201526009820154610120820152600a820154610140820152600b820154610160820152600c820154610180820152600d8201546101a0820152600e8201546101c08201529091506124719086613567565b604080516101e08101825283548152600184015460208201526002840154918101919091526003830154606082015260048301546080820152600583015460a0820152600683015460c0820152600783015460e082015260088301546101008201526009830154610120820152600a830154610140820152600b830154610160820152600c830154610180820152600d8301546101a0820152600e8301546101c082015290945061252290866135c1565b604080516101e08101825283548152600184015460208201526002840154918101919091526003830154606082015260048301546080820152600583015460a0820152600683015460c0820152600783015460e082015260088301546101008201526009830154610120820152600a830154610140820152600b830154610160820152600c830154610180820152600d8301546101a0820152600e8301546101c08201529093506125d39086613611565b9150509250925092565b6125e5613fe3565b6125ed613fe3565b60005b600460ff8216101561122a5761261560118260ff1660048110611805576118056143ac565b1561270d576126f261262882600161450f565b60118360ff166004811061263e5761263e6143ac565b600f0201604051806101e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e8201548152505061347490919063ffffffff16565b828260ff1660048110612707576127076143ac565b60200201525b6001016125f0565b60008060005b600460ff8216101561122a5761274060118260ff1660048110611805576118056143ac565b156127715760118160ff166004811061275b5761275b6143ac565b600f0201600901548261276e91906143f9565b91505b60010161271b565b6000611336612787836132fd565b604080516101e08101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e082015260088201546101008201526009820154610120820152600a820154610140820152600b820154610160820152600c820154610180820152600d8201546101a0820152600e909101546101c0820152613661565b60008061283d836120d5565b905060008160ff16116128925760405162461bcd60e51b815260206004820152601d60248201527f686173206e6f20706c616e65742077697468206365727461696e206964000000604482015260640161045f565b601161289f600183614393565b60ff16600481106128b2576128b26143ac565b600f02019150915091565b604080516101e08101825283548152600184015460208201526002840154918101919091526003830154606082015260048301546080820152600583015460a0820152600683015460c0820152600783015460e082015260088301546101008201526009830154610120820152600a830154610140820152600b830154610160820152600c830154610180820152600d8301546101a0820152600e8301546101c082015261296a90613387565b6129b15760405162461bcd60e51b815260206004820152601860248201527774686520706c616e6574206973206e6f742065786973747360401b604482015260640161045f565b6129b961311f565b6129c382826133ab565b6129cb6131a4565b604080516101e08101825283548152600184015460208201526002840154918101919091526003830154606082015260048301546080820152600583015460a0820152600683015460c0820152600783015460e082015260088301546101008201526009830154610120820152600a830154610140820152600b830154610160820152600c830154610180820152600d8301546101a0820152600e8301546101c0820152612a7890613387565b612abf5760405162461bcd60e51b815260206004820152601860248201527774686520706c616e6574206973206e6f742065786973747360401b604482015260640161045f565b5050565b6000612ace82613387565b8015612ade5750612ade82613674565b80156118b05750612aee82613001565b6040840151612afe9060016143f9565b109392505050565b6000806000612b148461368b565b600180860154604080516101e081018252875481529287015460208401526002870154908301526003860154606083015260048601546080830152600586015460a0830152600686015460c0830152600786015460e083015260088601546101008301526009860154610120830152600a860154610140830152600b860154610160830152600c860154610180830152600d8601546101a0830152600e8601546101c0830152612bc49190613022565b600180870154604080516101e081018252885481529288015460208401526002880154908301526003870154606083015260048701546080830152600587015460a0830152600687015460c0830152600787015460e083015260088701546101008301526009870154610120830152600a870154610140830152600b870154610160830152600c870154610180830152600d8701546101a0830152600e8701546101c0830152919450612c7691613089565b600180870154604080516101e081018252885481529288015460208401526002880154908301526003870154606083015260048701546080830152600587015460a0830152600687015460c0830152600787015460e083015260088701546101008301526009870154610120830152600a870154610140830152600b870154610160830152600c870154610180830152600d8701546101a0830152600e8701546101c0830152919350612d28916130d4565b90506001612dd785604051806101e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e82015481525050613001565b612de191906144ab565b60028601558215612eb4576000866001600160a01b03168460405160006040518083038185875af1925050503d8060008114612e39576040519150601f19603f3d011682016040523d82523d6000602084013e612e3e565b606091505b5050905080612e995760405162461bcd60e51b815260206004820152602160248201527f73656e7420666565206572726f723a206574686572206973206e6f742073656e6044820152601d60fa1b606482015260840161045f565b83856005016000828254612ead91906144ab565b9091555050505b8115612f4c57600a5460405163a9059cbb60e01b81526001600160a01b038881166004830152602482018590529091169063a9059cbb906044016020604051808303816000875af1158015612f0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f319190614472565b5081846006016000828254612f4691906144ab565b90915550505b8015612fe457600b5460405163a9059cbb60e01b81526001600160a01b038881166004830152602482018490529091169063a9059cbb906044016020604051808303816000875af1158015612fa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fc99190614472565b5080846007016000828254612fde91906144ab565b90915550505b612fed846138e7565b93509350939050565b60006117b982612831565b6000816040015182602001514261301891906144ab565b6113369190614053565b6000811580613037575061303583613387565b155b1561304457506000611336565b600061304f846139e5565b90508060000361306a5761306284613a07565b915050611336565b808361307586613a07565b61307f9190614026565b6121fa9190614053565b600081158061309e575061309c83613387565b155b156130ab57506000611336565b60006130b6846139e5565b9050806000036130c957613062846131d3565b8083613075866131d3565b60008115806130e957506130e783613387565b155b156130f657506000611336565b6000613101846139e5565b9050806000036131145761306284613a3d565b808361307586613a3d565b60015b600460ff8216116119925761315a601161313d600184614393565b60ff1660048110613150576131506143ac565b600f020182613a73565b50613164816144d7565b9050613122565b60005b600460ff821610156119925761319c60118260ff1660048110613193576131936143ac565b600f020161368b565b60010161316e565b604e544210156131b057565b60006131ba613ccc565b90508060ff166000036131ca5750565b611992816133c7565b60006131de82613387565b6131ea57506000919050565b6131f382613d1f565b15613200575060c0015190565b506101a0015190565b919050565b600080821161325f5760405162461bcd60e51b815260206004820152601e60248201527f706c616e657420776974682069643d30206973206e6f74206578697374730000604482015260640161045f565b60005b600460ff821610156132e4576001600160a01b0384166000908152604d6020526040812060ff83166004811061329a5761329a6143ac565b600302019050838160000154036132db5780546132b6906117c0565b6132d25760405162461bcd60e51b815260040161045f90614431565b91506113369050565b50600101613262565b5060405162461bcd60e51b815260040161045f90614431565b600060018260ff16101580156133175750600460ff831611155b61335d5760405162461bcd60e51b815260206004820152601760248201527634b731b7b93932b1ba10383630b732ba10373ab6b132b960491b604482015260640161045f565b601161336a600184614393565b60ff166004811061337d5761337d6143ac565b600f020192915050565b80516000901580159061133657506080820151158061133657505060800151421090565b6133b58282613a73565b156133be575050565b612abf8261368b565b60006133d2826132fd565b9050600c600081546133e3906144f6565b918290555081556007546008546000916133fc91613d39565b9050600061340e600554600654613d39565b905061341a81836143f9565b60028401556003830182905542600184015561343583613d6c565b613442603c610e10613d39565b61344c90426143f9565b604e5550505050565b600061346082613387565b61346c57506000919050565b5060a0015190565b61347c613f5d565b60405180608001604052808481526020016040518061014001604052806134a287613001565b81526020016134b087613a07565b81526020016134be876131d3565b81526020016134cc87613a3d565b81526020016134da876139e5565b81526020016134e887613674565b151581526020016134f887613d1f565b1515815260200161350887613dd1565b815260200161351687613df2565b815260200161352487613e0c565b9052815260ff8416602082015260400161353d85613387565b151590529392505050565b600061355382613387565b61355f57506000919050565b5060e0015190565b600081158061357c575061357a83613387565b155b1561358957506000611336565b8261012001516000036135a1575060a0820151611336565b826101200151828460a001516135b79190614026565b6118b09190614053565b60008115806135d657506135d483613387565b155b156135e357506000611336565b8261012001516000036135fb575060c0820151611336565b826101200151828460c001516135b79190614026565b6000811580613626575061362483613387565b155b1561363357506000611336565b82610120015160000361364b575060e0820151611336565b826101200151828460e001516135b79190614026565b8051600090158015906113365750611336825b6000816060015161368483613dd1565b1092915050565b604080516101e08101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e082015260088201546101008201526009820154610120820152600a820154610140820152600b820154610160820152600c820154610180820152600d8201546101a0820152600e8201546101c082015261373890613387565b15806137475750600481015415155b806137fc5750604080516101e08101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e082015260088201546101008201526009820154610120820152600a820154610140820152600b820154610160820152600c820154610180820152600d8201546101a0820152600e8201546101c08201526137fa90613d1f565b155b156138045750565b61380d81613d6c565b6009810154600b8201819055604080516101e08101825283548152600184015460208201526002840154918101919091526003830154606082015260048301546080820152600583015460a0820152600683015460c0820152600783015460e082015260088301546101008201526101208101829052600a830154610140820152610160810191909152600c820154610180820152600d8201546101a0820152600e8201546101c08201526138c190613001565b600a8201556005810154600c8201556006810154600d8201556007810154600e90910155565b604080516101e08101825282548152600183015460208201526002830154918101919091526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e082015260088201546101008201526009820154610120820152600a820154610140820152600b820154610160820152600c820154610180820152600d8201546101a0820152600e8201546101c082015261399490613387565b15806139a35750600481015415155b156139ab5750565b6009546139b9600182613d39565b6139c39190614528565b6001146139cd5750565b6119926139de600354600454613d39565b8290613e21565b60006139f082613d1f565b156139fe5750610120015190565b50610160015190565b6000613a1282613387565b613a1e57506000919050565b613a2782613d1f565b15613a34575060a0015190565b50610180015190565b6000613a4882613387565b613a5457506000919050565b613a5d82613d1f565b15613a6a575060e0015190565b506101c0015190565b600060018260ff1610158015613a8d5750600460ff831611155b613ad35760405162461bcd60e51b815260206004820152601760248201527634b731b7b93932b1ba10383630b732ba10373ab6b132b960491b604482015260640161045f565b604080516101e08101825284548152600185015460208201526002850154918101919091526003840154606082015260048401546080820152600584015460a0820152600684015460c0820152600784015460e082015260088401546101008201526009840154610120820152600a840154610140820152600b840154610160820152600c840154610180820152600d8401546101a0820152600e8401546101c0820152613b8090613e37565b613b8c57506000611336565b600083600901548460060154613ba291906143f9565b90508015613c2257600a5460405163a9059cbb60e01b815260006004820152602481018390526001600160a01b039091169063a9059cbb906044016020604051808303816000875af1158015613bfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c209190614472565b505b6011613c2f600185614393565b60ff1660048110613c4257613c426143ac565b600f0201600080820160009055600182016000905560028201600090556003820160009055600482016000905560058201600090556006820160009055600782016000905560088201600090556009820160009055600a820160009055600b820160009055600c820160009055600d820160009055600e8201600090555050600191505092915050565b6000805b600460ff82161015613d175760118160ff1660048110613cf257613cf26143ac565b600f020154600003613d0f57613d0981600161450f565b91505090565b600101613cd0565b506000905090565b6000613d2a82613001565b82610140015114159050919050565b6000613d4583836144ab565b613d509060016143f9565b613d58613e60565b613d629190614528565b6118b090846143f9565b613d74613e82565b816005016000828254613d8791906143f9565b90915550613d959050613eb1565b816006016000828254613da891906143f9565b90915550613db69050613ecc565b816007016000828254613dc991906143f9565b909155505050565b60008160400151826020015142613de891906144ab565b6113369190614528565b6000613dfd82613dd1565b826040015161133691906144ab565b6000613e1782613df2565b61133690426143f9565b613e2b81426143f9565b82600401819055505050565b805160009015801590613e4e575060008260800151115b80156113365750506080015142101590565b6010805460009143919083613e74836144f6565b919050556119379190614026565b60006103e8613e95600154600254613d39565b613e9d611f60565b613ea79190614026565b6119379190614053565b60006103e8613ec4600154600254613d39565b613e9d6118b7565b60006103e8613edf600154600254613d39565b613e9d612202565b604051806101e001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060800160405280613f70613ee7565b8152602001613fcf60405180610140016040528060008152602001600081526020016000815260200160008152602001600081526020016000151581526020016000151581526020016000815260200160008152602001600081525090565b815260006020820181905260409091015290565b60405180608001604052806004905b613ffa613f5d565b815260200190600190039081613ff25790505090565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761133657611336614010565b634e487b7160e01b600052601260045260246000fd5b6000826140625761406261403d565b500490565b60006020828403121561407957600080fd5b5035919050565b805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a0808201519083015260c0808201519083015260e08082015190830152610100808201519083015261012080820151908301526101408082015190830152610160808201519083015261018080820151908301526101a080820151908301526101c090810151910152565b6101e081016113368284614080565b80356001600160a01b038116811461320957600080fd5b6000806040838503121561415157600080fd5b8235915061416160208401614127565b90509250929050565b60006020828403121561417c57600080fd5b6118b082614127565b6000806040838503121561419857600080fd5b6141a183614127565b915061416160208401614127565b600080604083850312156141c257600080fd5b6141cb83614127565b946020939093013593505050565b81518152602080830151908201526040808301519082015260608101611336565b6000806040838503121561420d57600080fd5b50508035926020909101359150565b60006020828403121561422e57600080fd5b813560ff811681146118b057600080fd5b6020808252825182820181905260009190848201906040850190845b81811015614295576142828385518051825260208082015190830152604090810151910152565b928401926060929092019160010161425b565b50909695505050505050565b6142ac828251614080565b602081015180516101e0840152602081015161020084015260408101516102208401526060810151610240840152608081015161026084015260a08101516142f961028085018215159052565b5060c081015115156102a084015260e08101516102c08401526101008101516102e08401526101200151610300830152604081015160ff1661032083015260600151151561034090910152565b610360810161133682846142a1565b610d808101818360005b600481101561438a576143738383516142a1565b61036092909201916020919091019060010161435f565b50505092915050565b60ff828116828216039081111561133657611336614010565b634e487b7160e01b600052603260045260246000fd5b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b8082018082111561133657611336614010565b6020808252600b908201526a1b9bdd0818dbdc9c9958dd60aa1b604082015260600190565b60208082526021908201527f6164647265737320736c6f7420666f7220706c616e6574206e6f7420666f756e6040820152601960fa1b606082015260800190565b60006020828403121561448457600080fd5b815180151581146118b057600080fd5b6000816144a3576144a3614010565b506000190190565b8181038181111561133657611336614010565b6000602082840312156144d057600080fd5b5051919050565b600060ff821660ff81036144ed576144ed614010565b60010192915050565b60006001820161450857614508614010565b5060010190565b60ff818116838216019081111561133657611336614010565b6000826145375761453761403d565b50069056fea26469706673582212202ae90e05b86983ea6d2a0ee7cb834c010fdf538dfb01b28a32afe342eb192a0964736f6c63430008190033
Verified Source Code Full Match
Compiler: v0.8.25+commit.b61c2a91
EVM: paris
Optimization: Yes (200 runs)
IERC20.sol 79 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
AccPlanetData.sol 7 lines
pragma solidity ^0.8.21;
struct AccPlanetData {
uint256 planetId; // id of the planet or 0
uint256 tokenStaked; // count of staked tokens of account
uint256 claimPeriod; // last used claim period
}
ISpace.sol 5 lines
pragma solidity ^0.8.21;
interface ISpace {
function executeNewPlanets() external;
}
Planet.sol 24 lines
pragma solidity ^0.8.21;
struct Planet {
// constant for planet
uint256 id; // id of planet or 0 if it not exists
uint256 creationTime; // when was created
uint256 periodTimer; // period time interval
uint256 claimResourcesTimer; // time seconds to extract resources on new claim period
// destruction
uint256 destroyTime; // time when will be destroyed or 0
// total savings
uint256 eth; // eth to claim
uint256 token; // token to claim
uint256 token2; // token2 to claim
// accounts data
uint256 accountsCount; // accounts count on planet
uint256 tokenStaked; // total staked tokens
// snapshot
uint256 claimPeriodSnapshot; // number of snapshot period to claim
uint256 tokenStakedSnapshot; // tokens staked for claims on claim period
uint256 ethSnapshot;
uint256 tokenSnapshot;
uint256 token2Snapshot;
}
PlanetPrediction.sol 190 lines
pragma solidity ^0.8.21;
import "./Planet.sol";
struct Period {
uint256 number; // period number
uint256 eth; // ether on period for rewards
uint256 token; // token on period (not includes stakes) for rewards
uint256 token2; // token2 on period for rewards
uint256 tokenStaked; // token stacks sum on period
bool isClaimTime; // is now claim time or not
bool isDirty; // is period dirty
uint256 time; // time since the beginning of the period
uint256 remainingTime; // remaining time until next period
uint256 endTime; // when period expires
}
struct PlanetData {
Planet planet; // planet data
Period period; // planet period data
uint8 number; // planet number
bool isExists; // is planet exists
}
library PlanetPrediction {
// time from period start
function periodTime(Planet memory planet) internal view returns (uint256) {
return (block.timestamp - planet.creationTime) % planet.periodTimer;
}
function nextPeriodRemainingTime(
Planet memory planet
) internal view returns (uint256) {
return planet.periodTimer - periodTime(planet);
}
function nextPeriodTime(
Planet memory planet
) internal view returns (uint256) {
return block.timestamp + nextPeriodRemainingTime(planet);
}
function periodNumber(
Planet memory planet
) internal view returns (uint256) {
return (block.timestamp - planet.creationTime) / planet.periodTimer;
}
function isClaimPeriodDirty(
Planet memory planet
) internal view returns (bool) {
return planet.claimPeriodSnapshot != periodNumber(planet);
}
function isClaimTime(Planet memory planet) internal view returns (bool) {
return periodTime(planet) < planet.claimResourcesTimer;
}
function ethOnPlanet(Planet memory planet) internal view returns (uint256) {
if (!isExists(planet)) return 0;
return planet.eth;
}
function token2OnPlanet(
Planet memory planet
) internal view returns (uint256) {
if (!isExists(planet)) return 0;
return planet.token2;
}
function ethOnPeriod(Planet memory planet) internal view returns (uint256) {
if (!isExists(planet)) return 0;
if (isClaimPeriodDirty(planet)) return planet.eth;
else return planet.ethSnapshot;
}
function tokenOnPeriod(
Planet memory planet
) internal view returns (uint256) {
if (!isExists(planet)) return 0;
if (isClaimPeriodDirty(planet)) return planet.token;
else return planet.tokenSnapshot;
}
function token2OnPeriod(
Planet memory planet
) internal view returns (uint256) {
if (!isExists(planet)) return 0;
if (isClaimPeriodDirty(planet)) return planet.token2;
else return planet.token2Snapshot;
}
function tokenStakedOnPeriod(
Planet memory planet
) internal view returns (uint256) {
if (isClaimPeriodDirty(planet)) return planet.tokenStaked;
else return planet.tokenStakedSnapshot;
}
function ethRewardForTokens(
Planet memory planet,
uint256 tokenstaked
) internal view returns (uint256) {
if (tokenstaked == 0 || !isExists(planet)) return 0;
if (planet.tokenStaked == 0) return planet.eth;
return (planet.eth * tokenstaked) / planet.tokenStaked;
}
function tokenRewardForTokens(
Planet memory planet,
uint256 tokenstaked
) internal view returns (uint256) {
if (tokenstaked == 0 || !isExists(planet)) return 0;
if (planet.tokenStaked == 0) return planet.token;
return (planet.token * tokenstaked) / planet.tokenStaked;
}
function token2RewardForTokens(
Planet memory planet,
uint256 tokenstaked
) internal view returns (uint256) {
if (tokenstaked == 0 || !isExists(planet)) return 0;
if (planet.tokenStaked == 0) return planet.token2;
return (planet.token2 * tokenstaked) / planet.tokenStaked;
}
function ethRewardPeriod(
Planet memory planet,
uint256 tokenstaked
) internal view returns (uint256) {
if (tokenstaked == 0 || !isExists(planet)) return 0;
uint256 stacke = tokenStakedOnPeriod(planet);
if (stacke == 0) return ethOnPeriod(planet);
return (ethOnPeriod(planet) * tokenstaked) / stacke;
}
function tokenRewardPeriod(
Planet memory planet,
uint256 tokenstaked
) internal view returns (uint256) {
if (tokenstaked == 0 || !isExists(planet)) return 0;
uint256 stacke = tokenStakedOnPeriod(planet);
if (stacke == 0) return tokenOnPeriod(planet);
return (tokenOnPeriod(planet) * tokenstaked) / stacke;
}
function token2RewardPeriod(
Planet memory planet,
uint256 tokenstaked
) internal view returns (uint256) {
if (tokenstaked == 0 || !isExists(planet)) return 0;
uint256 stacke = tokenStakedOnPeriod(planet);
if (stacke == 0) return token2OnPeriod(planet);
return (token2OnPeriod(planet) * tokenstaked) / stacke;
}
function isExists(Planet memory planet) internal view returns (bool) {
return
planet.id > 0 &&
(planet.destroyTime == 0 || (block.timestamp < planet.destroyTime));
}
function getData(
Planet memory planet,
uint8 number
) internal view returns (PlanetData memory) {
return
PlanetData(
planet,
Period(
periodNumber(planet),
ethOnPeriod(planet),
tokenOnPeriod(planet),
token2OnPeriod(planet),
tokenStakedOnPeriod(planet),
isClaimTime(planet),
isClaimPeriodDirty(planet),
periodTime(planet),
nextPeriodRemainingTime(planet),
nextPeriodTime(planet)
),
number,
isExists(planet)
);
}
function setDestroyTimer(Planet storage planet, uint256 timer) internal {
planet.destroyTime = block.timestamp + timer;
}
}
ThePirateBayGame.sol 654 lines
pragma solidity ^0.8.21;
import "./ISpace.sol";
import "./Planet.sol";
import "./AccPlanetData.sol";
import "./PlanetPrediction.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract Ownable {
address _owner;
constructor() {
_owner = msg.sender;
}
modifier onlyOwner() {
require(_owner == msg.sender, "caller is not the owner");
_;
}
function owner() external view virtual returns (address) {
return _owner;
}
function renounceOwnership(address newOwner) external onlyOwner {
_owner = newOwner;
}
}
contract ThePirateBayGame is ISpace, Ownable {
using PlanetPrediction for Planet;
address public immutable dev;
uint256 public minPlanetRewardPercent = 50; // 100%=1000
uint256 public maxPlanetRewardPercent = 500; // 100%=1000
uint8 constant _startPlanetsCount = 2;
uint8 public constant maxPlanetsCount = 4; // maximum planets count
uint256 public constant newPlanetTimeMin = 1 minutes;
uint256 public constant newPlanetTimeMax = 1 hours;
uint256 public planetDestructionTimeMin = 60 seconds;
uint256 public planetDestructionTimeMax = 600 seconds;
uint256 public planetPeriodWaitTimerMin = 60 seconds; // planet period wait time interval min
uint256 public planetPeriodWaitTimerMax = 36000 seconds; // planet period wait time interval max
uint256 public planetClaimResourcesTimerMin = 60 seconds; // planet claim time interval min
uint256 public planetClaimResourcesTimerMax = 3600 seconds; // planet claim time interval max
uint256 public destructionStartProb = 30; // noe of this is starts destruction on claim
IERC20 public erc20;
IERC20 public erc202;
uint256 public totalCreatedPlanets; // total created planets count
bool public isStarted;
uint256 _devFeePercent = 50; // dev fee percent
address _deployer;
uint256 internal _nonce = 1;
Planet[maxPlanetsCount] _planets; // accounts planet data
mapping(address => AccPlanetData[maxPlanetsCount]) accs;
uint256 _newPlanetTime;
constructor(address dev_) {
_deployer = msg.sender;
dev = dev_;
}
function start() external onlyOwner {
require(!isStarted, "already started");
isStarted = true;
for (uint8 i = 1; i <= _startPlanetsCount; ++i) _createPlanet(i);
}
function setPeriodWaitTimer(
uint256 planetPeriodWaitTimerMin_,
uint256 planetPeriodWaitTimerMax_
) external onlyOwner {
require(
planetPeriodWaitTimerMin_ > 0 &&
planetPeriodWaitTimerMin_ <= planetPeriodWaitTimerMax_,
"not correct"
);
planetPeriodWaitTimerMin = planetPeriodWaitTimerMin_;
planetPeriodWaitTimerMax = planetPeriodWaitTimerMax_;
}
function setClaimResourcesTimer(
uint256 planetClaimResourcesTimerMin_,
uint256 planetClaimResourcesTimerMax_
) external onlyOwner {
require(
planetClaimResourcesTimerMin_ > 0 &&
planetClaimResourcesTimerMin_ <= planetClaimResourcesTimerMax_,
"not correct"
);
planetClaimResourcesTimerMin = planetClaimResourcesTimerMin_;
planetClaimResourcesTimerMax = planetClaimResourcesTimerMax_;
}
function setRewardPercent(uint256 min, uint256 max) external onlyOwner {
require(min <= max, "not correct");
require(max <= 1000, "not correct");
minPlanetRewardPercent = min;
maxPlanetRewardPercent = max;
}
function setDestructionStartProb(uint256 prob) external onlyOwner {
require(prob > 1);
destructionStartProb = prob;
}
function setErc20(address erc20_, address erc202_) external {
require(msg.sender == _deployer);
delete _deployer;
erc20 = IERC20(erc20_);
erc202 = IERC20(erc202_);
}
receive() external payable {
uint256 devFee = (msg.value * _devFeePercent) / 100;
(bool sentFee, ) = payable(dev).call{value: devFee}("");
require(sentFee, "sent fee error: dev ether is not sent");
}
function devFeePercent() external view returns (uint256) {
return _devFeePercent;
}
function setDevFeePercent(uint256 percent) external onlyOwner {
require(percent <= 50);
_devFeePercent = percent;
}
function goToPlanet(uint256 planetId, uint256 tokensCount) external {
// limitations
require(isStarted, "not started");
// First, execute updates (including planet destructions)
_executePlanetsDestructions();
// Check if the planet still exists after destructions
if (!isPlanetExists(planetId)) {
revert("planet is not exists");
}
// Fetch the current planet data
(Planet storage planet, uint8 number) = _getPlanetByIdInternal(
planetId
);
// Update the planet
_updatePlanet(planet, number);
_executeNewPlanets();
require(planet.isExists(), "planet is not exists");
// thansfer stak tokens
uint256 lastTokens = erc20.balanceOf(address(this));
erc20.transferFrom(msg.sender, address(this), tokensCount);
uint256 staked = erc20.balanceOf(address(this)) - lastTokens;
// write data
AccPlanetData storage acc = accs[msg.sender][number - 1];
if (acc.planetId != planet.id) ++planet.accountsCount;
acc.planetId = planet.id;
acc.claimPeriod = planet.periodNumber();
acc.tokenStaked += staked;
planet.tokenStaked += staked;
}
function leavePlanet(uint256 planetId) external {
(Planet storage planet, uint8 number) = _getPlanetByIdInternal(
planetId
);
_updateBeforeUsePlanet(planet, number);
// Get exact account slot by planetId to prevent mixing states after planet replacement
AccPlanetData storage acc = _getAccSlotForPlanet(msg.sender, planetId);
require(acc.planetId > 0, "address slot for planet not found");
// if (_canClaimRewards(acc, planet))
// _claimRewards(msg.sender, acc, planet);
erc20.transfer(msg.sender, acc.tokenStaked);
--planet.accountsCount;
// Explicit guard for arithmetic safety and state consistency
require(planet.tokenStaked >= acc.tokenStaked, "inconsistent planet/account stake");
planet.tokenStaked -= acc.tokenStaked;
// Delete the slot corresponding to current planet number
delete accs[msg.sender][number - 1];
}
function _updateBeforeUsePlanet(
Planet storage planet,
uint8 number
) private {
require(planet.isExists(), "the planet is not exists");
_executePlanetsDestructions();
_updatePlanet(planet, number);
_executeNewPlanets();
require(planet.isExists(), "the planet is not exists");
}
function getAccSlots(
address addr
) external view returns (AccPlanetData[] memory) {
AccPlanetData[] memory res = new AccPlanetData[](maxPlanetsCount);
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
AccPlanetData storage data = accs[addr][i];
Planet memory planet = _planets[i];
// Return slot only if the planet in this slot exists AND matches stored planetId
if (!planet.isExists()) continue;
if (data.planetId != planet.id) continue;
res[i] = data;
}
return res;
}
function getAccSlotForPlanet(
address acc,
uint256 planetId
) public view returns (AccPlanetData memory) {
return _getAccSlotForPlanet(acc, planetId);
}
function _getAccSlotForPlanet(
address acc,
uint256 planetId
) private view returns (AccPlanetData storage) {
require(planetId > 0, "planet with id=0 is not exists");
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
AccPlanetData storage data = accs[acc][i];
if (data.planetId == planetId) {
require(
isPlanetExists(data.planetId),
"address slot for planet not found"
);
return data;
}
}
revert("address slot for planet not found");
}
function _trySetDestructionTime(Planet storage planet) private {
if (!planet.isExists() || planet.destroyTime != 0) return;
if (_rand(1, destructionStartProb) % destructionStartProb != 1) return;
planet.setDestroyTimer(
_rand(planetDestructionTimeMin, planetDestructionTimeMax)
);
}
function isPlanetClaimInterval(
uint8 planetNumber
) public view returns (bool) {
return _isPlanetClaimInterval(_getPlanetByNumber(planetNumber));
}
function _isPlanetClaimInterval(
Planet memory planet
) private view returns (bool) {
return planet.id > 0 && planet.isClaimTime();
}
/*function claimRewardsAllPlanets() external {
uint8 claimCount;
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
AccPlanetData storage data = accs[msg.sender][i];
Planet storage planet = _planets[i];
if (!planet.isExists()) continue;
_updatePlanet(planet, i + 1);
if (!_canClaimRewards(data, planet)) continue;
_claimRewards(msg.sender, data, planet);
++claimCount;
}
_executeNewPlanets();
require(claimCount > 0, "can not claim rewards yet");
}*/
function claimRewards(uint256 planetId) external {
(Planet storage planet, uint8 number) = _getPlanetByIdInternal(
planetId
);
_updateBeforeUsePlanet(planet, number);
AccPlanetData storage data = accs[msg.sender][number - 1];
require(_canClaimRewards(data, planet), "can not claim rewards yet");
_claimRewards(msg.sender, data, planet);
}
function _canClaimRewards(
AccPlanetData memory acc,
Planet memory planet
) private view returns (bool) {
return
planet.isExists() &&
planet.isClaimTime() &&
acc.claimPeriod + 1 < planet.periodNumber();
}
function _claimRewards(
address addr,
AccPlanetData storage acc,
Planet storage planet
)
private
returns (
uint256 ethRewarded,
uint256 tokenRewarded,
uint256 token2Rewarded
)
{
_tryNextClaimPeriodSnapshot(planet);
ethRewarded = planet.ethRewardPeriod(acc.tokenStaked);
tokenRewarded = planet.tokenRewardPeriod(acc.tokenStaked);
token2Rewarded = planet.token2RewardPeriod(acc.tokenStaked);
acc.claimPeriod = planet.periodNumber() - 1;
if (ethRewarded > 0) {
(bool sentFee, ) = payable(addr).call{value: ethRewarded}("");
require(sentFee, "sent fee error: ether is not sent");
planet.eth -= ethRewarded;
}
if (tokenRewarded > 0) {
erc20.transfer(addr, tokenRewarded);
planet.token -= tokenRewarded;
}
if (token2Rewarded > 0) {
erc202.transfer(addr, token2Rewarded);
planet.token2 -= token2Rewarded;
}
_trySetDestructionTime(planet);
}
function _tryNextClaimPeriodSnapshot(Planet storage planet) private {
if (
!planet.isExists() ||
planet.destroyTime != 0 ||
!planet.isClaimPeriodDirty()
) return;
_addRewardsToPlanet(planet);
planet.tokenStakedSnapshot = planet.tokenStaked;
planet.claimPeriodSnapshot = planet.periodNumber();
planet.ethSnapshot = planet.eth;
planet.tokenSnapshot = planet.token;
planet.token2Snapshot = planet.token2;
}
function getRewardForTokens(
uint256 planetId,
uint256 tokensCount
) external view returns (uint256 eth, uint256 token, uint256 token2) {
(Planet storage planet, ) = _getPlanetByIdInternal(planetId);
eth = planet.ethRewardForTokens(tokensCount);
token = planet.tokenRewardForTokens(tokensCount);
token2 = planet.token2RewardForTokens(tokensCount);
}
function getRewardForAccount(
uint256 planetId,
address account
) external view returns (uint256 eth, uint256 token, uint256 token2) {
(Planet storage planet, uint8 number) = _getPlanetByIdInternal(
planetId
);
AccPlanetData memory acc = accs[account][number - 1];
if (acc.claimPeriod == planet.periodNumber()) {
return (0, 0, 0);
}
eth = planet.ethRewardPeriod(acc.tokenStaked);
token = planet.tokenRewardPeriod(acc.tokenStaked);
token2 = planet.token2RewardPeriod(acc.tokenStaked);
}
function _getPlanetNumber(
AccPlanetData memory acc
) private view returns (uint8) {
if (acc.planetId == 0) return 0;
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
if (_planets[i].id == acc.planetId) return i + 1;
}
return 0;
}
function getPlanetByNumber(
uint8 number
) external view returns (Planet memory) {
return _getPlanetByNumber(number);
}
function _getPlanetByNumber(
uint8 number
) private view returns (Planet storage) {
require(
number >= 1 && number <= maxPlanetsCount,
"incorrect planet number"
);
return _planets[number - 1];
}
function getPlanetNumberById(uint256 id) public view returns (uint8) {
if (id == 0) return 0;
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
if (_planets[i].id == id) return i + 1;
}
return 0;
}
function isPlanetExists(uint256 id) public view returns (bool) {
uint8 planetNumber = getPlanetNumberById(id);
if (planetNumber == 0) return false;
return _planets[planetNumber - 1].isExists();
}
function getPlanetById(uint256 id) external view returns (Planet memory) {
return _getPlanetById(id);
}
function _getPlanetByIdInternal(
uint256 id
) private view returns (Planet storage planet, uint8 number) {
number = getPlanetNumberById(id);
require(number > 0, "has no planet with certain id");
planet = _planets[number - 1];
}
function _getPlanetById(
uint256 id
) internal view returns (Planet storage planet) {
(planet, ) = _getPlanetByIdInternal(id);
}
function getPlanetClaimPeriod(
uint256 planetId
) external view returns (uint256) {
return _getPlanetById(planetId).periodNumber();
}
function tokenStacked() public view returns (uint256) {
uint256 res;
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
if (!_planets[i].isExists()) continue;
res += _planets[i].tokenStaked;
}
return res;
}
function token2Total() public view returns (uint256) {
return erc202.balanceOf(address(this));
}
function ethOnPlanets() public view returns (uint256) {
uint256 res;
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
res += _planets[i].ethOnPlanet();
}
return res;
}
function tokenOnPlanets() public view returns (uint256) {
uint256 res;
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
res += _planets[i].tokenOnPeriod();
}
return res;
}
function tokenOnPlanetsRewardWithStacks() public view returns (uint256) {
uint256 res;
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
res += _planets[i].token + _planets[i].tokenStaked;
}
return res;
}
function token2OnPlanets() public view returns (uint256) {
uint256 res;
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
res += _planets[i].token2OnPlanet();
}
return res;
}
function accountsOnPlanets() public view returns (uint256) {
uint256 res;
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
res += _planets[i].accountsCount;
}
return res;
}
function planetsCount() public view returns (uint8) {
uint8 res;
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
if (_planets[i].id > 0) ++res;
}
return res;
}
function _getEmptyPlanetNumber() internal view returns (uint8) {
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
if (_planets[i].id == 0) return i + 1;
}
return 0;
}
function _rand() internal virtual returns (uint256) {
//return _nonce++ * block.timestamp * block.number;
return _nonce++ * block.number;
}
function _rand(uint256 min, uint256 max) private returns (uint256) {
return min + (_rand() % (max - min + 1));
}
function ethRewardsCount() public view returns (uint256) {
return address(this).balance - ethOnPlanets();
}
function tokenRewardsCount() public view returns (uint256) {
return
erc20.balanceOf(address(this)) - tokenOnPlanetsRewardWithStacks();
}
function token2RewardsCount() public view returns (uint256) {
return token2Total() - token2OnPlanets();
}
function _generatePlanetEth() private returns (uint256) {
return
(ethRewardsCount() *
_rand(minPlanetRewardPercent, maxPlanetRewardPercent)) / 1000;
}
function _generatePlanetToken() private returns (uint256) {
return
(tokenRewardsCount() *
_rand(minPlanetRewardPercent, maxPlanetRewardPercent)) / 1000;
}
function _generatePlanetToken2() private returns (uint256) {
return
(token2RewardsCount() *
_rand(minPlanetRewardPercent, maxPlanetRewardPercent)) / 1000;
}
function _addRewardsToPlanet(Planet storage planet) private {
planet.eth += _generatePlanetEth();
planet.token += _generatePlanetToken();
planet.token2 += _generatePlanetToken2();
}
function getPlanets()
external
view
returns (PlanetData[maxPlanetsCount] memory)
{
PlanetData[maxPlanetsCount] memory res;
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
if (!_planets[i].isExists()) continue;
res[i] = _planets[i].getData(i + 1);
}
return res;
}
function getPlanetData(
uint256 planetId
) external view returns (PlanetData memory) {
(Planet storage planet, uint8 number) = _getPlanetByIdInternal(
planetId
);
return planet.getData(number);
}
function _createPlanet(uint8 number) private {
Planet storage planet = _getPlanetByNumber(number);
planet.id = ++totalCreatedPlanets;
uint256 periodClaim = _rand(
planetClaimResourcesTimerMin,
planetClaimResourcesTimerMax
);
uint256 periodWait = _rand(
planetPeriodWaitTimerMin,
planetPeriodWaitTimerMax
);
planet.periodTimer = periodClaim + periodWait;
planet.claimResourcesTimer = periodClaim;
planet.creationTime = block.timestamp;
_addRewardsToPlanet(planet);
_newPlanetTime =
block.timestamp +
_rand(newPlanetTimeMin, newPlanetTimeMax);
}
function _isNeedDestroyPlanet(
Planet memory planet
) private view returns (bool) {
return planet.id > 0 && planet.destroyTime > 0 && block.timestamp >= planet.destroyTime;
}
function executeNewPlanets() external {
_executeNewPlanets();
}
function _executeNewPlanets() private {
// time limit
if (block.timestamp < _newPlanetTime) return;
// getting new planet number
uint8 newPlanetNumber = _getEmptyPlanetNumber();
if (newPlanetNumber == 0) return;
// creating the new planet
_createPlanet(newPlanetNumber);
}
function updatePlanet(uint8 number) external {
_updatePlanet(_getPlanetByNumber(number), number);
_executeNewPlanets();
}
function _updatePlanet(Planet storage planet, uint8 number) private {
if (_destroyPlanet(planet, number)) return;
_tryNextClaimPeriodSnapshot(planet);
}
function _executePlanetsDestructions() private {
for (uint8 i = 1; i <= maxPlanetsCount; ++i) {
_destroyPlanet(_planets[i - 1], i);
}
}
function _destroyPlanet(
Planet storage planet,
uint8 number
) private returns (bool) {
require(
number >= 1 && number <= maxPlanetsCount,
"incorrect planet number"
);
if (!_isNeedDestroyPlanet(planet)) return false;
uint256 tokenToBurn = planet.token + planet.tokenStaked;
if (tokenToBurn > 0) erc20.transfer(address(0), tokenToBurn);
delete _planets[number - 1];
return true;
}
function _executePlanetsClaimPeriods() private {
for (uint8 i = 0; i < maxPlanetsCount; ++i) {
_tryNextClaimPeriodSnapshot(_planets[i]);
}
}
function executePlanets() external {
_executePlanetsDestructions();
_executePlanetsClaimPeriods();
_executeNewPlanets();
}
}
Read Contract
accountsOnPlanets 0x75590695 → uint256
destructionStartProb 0x48fe494e → uint256
dev 0x91cca3db → address
devFeePercent 0x3f64a7ab → uint256
erc20 0x785e9e86 → address
erc202 0x450ca5b5 → address
ethOnPlanets 0xc2169da2 → uint256
ethRewardsCount 0xc20741b6 → uint256
getAccSlotForPlanet 0x4e9ac208 → tuple
getAccSlots 0x9ddf9351 → tuple[]
getPlanetById 0x261b8fb2 → tuple
getPlanetByNumber 0x5beafaf3 → tuple
getPlanetClaimPeriod 0x4dcc33a3 → uint256
getPlanetData 0xdc9ce7a5 → tuple
getPlanetNumberById 0xd6796d98 → uint8
getPlanets 0xf32bb423 → tuple[4]
getRewardForAccount 0x32845545 → uint256, uint256, uint256
getRewardForTokens 0xf13da005 → uint256, uint256, uint256
isPlanetClaimInterval 0xff0f7b0f → bool
isPlanetExists 0xa0c8883a → bool
isStarted 0x544736e6 → bool
maxPlanetRewardPercent 0xc0e4727c → uint256
maxPlanetsCount 0xe4109e4d → uint8
minPlanetRewardPercent 0x64148ec8 → uint256
newPlanetTimeMax 0x839fe776 → uint256
newPlanetTimeMin 0x2ba677e2 → uint256
owner 0x8da5cb5b → address
planetClaimResourcesTimerMax 0xd37a6cc9 → uint256
planetClaimResourcesTimerMin 0x45b4a7e7 → uint256
planetDestructionTimeMax 0x8253b8e2 → uint256
planetDestructionTimeMin 0x0e1d8d3e → uint256
planetPeriodWaitTimerMax 0xaeee9b5b → uint256
planetPeriodWaitTimerMin 0xf355eff0 → uint256
planetsCount 0xe9c07b42 → uint8
token2OnPlanets 0xeddbc0e5 → uint256
token2RewardsCount 0xe3a6bcd5 → uint256
token2Total 0xe3d258a5 → uint256
tokenOnPlanets 0x3baa9ad3 → uint256
tokenOnPlanetsRewardWithStacks 0xbe22a03e → uint256
tokenRewardsCount 0xa24a29d7 → uint256
tokenStacked 0xf5dabbef → uint256
totalCreatedPlanets 0xc4a9e872 → uint256
Write Contract 14 functions
These functions modify contract state and require a wallet transaction to execute.
claimRewards 0x0962ef79
uint256 planetId
executeNewPlanets 0xf2e0bf50
No parameters
executePlanets 0x38d0c2e8
No parameters
goToPlanet 0xc06ee0ad
uint256 planetId
uint256 tokensCount
leavePlanet 0x9c3f5a83
uint256 planetId
renounceOwnership 0x38bf3cfa
address newOwner
setClaimResourcesTimer 0xb4976dd1
uint256 planetClaimResourcesTimerMin_
uint256 planetClaimResourcesTimerMax_
setDestructionStartProb 0xa2cb1be2
uint256 prob
setDevFeePercent 0x379e2919
uint256 percent
setErc20 0x3d8c4f7d
address erc20_
address erc202_
setPeriodWaitTimer 0x537c9d80
uint256 planetPeriodWaitTimerMin_
uint256 planetPeriodWaitTimerMax_
setRewardPercent 0xc79bdb46
uint256 min
uint256 max
start 0xbe9a6555
No parameters
updatePlanet 0xa8972909
uint8 number
Recent Transactions
No transactions found for this address