Address Contract Partially Verified
Address
0x5f5fF74B198E5095069cF132D2523DBaE516613f
Balance
0.130374 ETH
Nonce
1
Code Size
19091 bytes
Creator
0x881eB9c9...Ef40 at tx 0x9abe8d10...d1610d
Indexed Transactions
0
Contract Bytecode
19091 bytes
0x6080604052600436106102c65763ffffffff60e060020a6000350416630519ce79811461032057806305e455461461035157806306fdde0314610378578063095ea7b3146104025780630a0f8168146104265780630e583df01461043b57806314001f4c1461045057806318160ddd146104715780631940a9361461048657806319c2f201146104b25780631caa79f9146104c757806321717ebf146104dc57806323b872dd146104f157806324e7a38a1461051b57806327d7874c1461053c5780632ba73c151461055d5780633304cbff1461057e5780633d7d3f5a146105935780633f4ba83a146105b457806346a89ada146105c957806346d22c70146105ea57806348648a6f146106055780634ad8c938146106165780634b85fd55146106375780634dfff04f1461064f5780634e0a33791461067357806353d8909414610694578063562340cf146106a95780635c975abb146106c15780635fd8c710146106d65780636352211e146106eb578063680eba27146107035780636af04a57146107185780636fbde40d1461072d57806370a082311461074e578063715879881461076f5780637a87bb911461079057806382877bf0146107b15780638456cb59146107d25780638462151c146107e757806388c2a0bf1461085857806395d89b411461087057806396baf2bd146108855780639c1cb8bf146108a65780639c56e5d7146108b4578063a6531d34146108d2578063a9059cbb146108e7578063b047fb501461090b578063b0c35c0514610920578063c0e9b0c214610935578063d3e6f49f1461095f578063d75b855a14610977578063defb95841461098c578063e065efbb146109a1578063e06f96e2146109c8578063e23d5314146109dd578063e4c73abe146109fb578063e6cbe35114610a10578063ed60ade614610a25578063f1ca941014610a33578063f2b47d5214610a48578063f7d8c88314610a5d575b600454600160a060020a03163314806102e95750600554600160a060020a031633145b806102fe5750600654600160a060020a031633145b806103135750600754600160a060020a031633145b151561031e57600080fd5b005b34801561032c57600080fd5b50610335610a6b565b60408051600160a060020a039092168252519081900360200190f35b34801561035d57600080fd5b50610366610a7a565b60408051918252519081900360200190f35b34801561038457600080fd5b5061038d610a80565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103c75781810151838201526020016103af565b50505050905090810190601f1680156103f45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561040e57600080fd5b5061031e600160a060020a0360043516602435610ab7565b34801561043257600080fd5b50610335610b39565b34801561044757600080fd5b50610366610b48565b34801561045c57600080fd5b5061031e600160a060020a0360043516610b54565b34801561047d57600080fd5b50610366610c1e565b34801561049257600080fd5b5061049e600435610ca7565b604080519115158252519081900360200190f35b3480156104be57600080fd5b50610366610cda565b3480156104d357600080fd5b50610366610ce1565b3480156104e857600080fd5b50610335610ce7565b3480156104fd57600080fd5b5061031e600160a060020a0360043581169060243516604435610cf6565b34801561052757600080fd5b5061031e600160a060020a0360043516610d72565b34801561054857600080fd5b5061031e600160a060020a0360043516610e3c565b34801561056957600080fd5b5061031e600160a060020a0360043516610ea1565b34801561058a57600080fd5b50610366610f06565b34801561059f57600080fd5b5061031e600435602435604435606435610f12565b3480156105c057600080fd5b5061031e611005565b3480156105d557600080fd5b5061031e600160a060020a036004351661110c565b3480156105f657600080fd5b5061049e6004356024356111d6565b61036660043560243560443561123e565b34801561062257600080fd5b5061031e600435602435604435606435611408565b34801561064357600080fd5b5061031e6004356114e0565b34801561065b57600080fd5b5061031e600160a060020a03600435166024356114fc565b34801561067f57600080fd5b5061031e600160a060020a03600435166115b2565b3480156106a057600080fd5b5061031e611617565b3480156106b557600080fd5b5061031e600435611826565b3480156106cd57600080fd5b5061049e611842565b3480156106e257600080fd5b5061031e611852565b3480156106f757600080fd5b5061033560043561194e565b34801561070f57600080fd5b506103666119e6565b34801561072457600080fd5b506103356119ec565b34801561073957600080fd5b5061031e600160a060020a03600435166119fb565b34801561075a57600080fd5b50610366600160a060020a0360043516611ac5565b34801561077b57600080fd5b5061031e600160a060020a0360043516611b62565b34801561079c57600080fd5b5061031e600160a060020a0360043516611bfc565b3480156107bd57600080fd5b5061031e600160a060020a0360043516611cc6565b3480156107de57600080fd5b5061031e611d90565b3480156107f357600080fd5b50610808600160a060020a0360043516611e25565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561084457818101518382015260200161082c565b505050509050019250505060405180910390f35b34801561086457600080fd5b50610366600435611f62565b34801561087c57600080fd5b5061038d6123e7565b34801561089157600080fd5b5061031e600160a060020a036004351661241e565b61031e6004356024356124e8565b3480156108c057600080fd5b50610366600435602435604435612725565b3480156108de57600080fd5b506103356127d3565b3480156108f357600080fd5b5061031e600160a060020a03600435166024356127e2565b34801561091757600080fd5b5061033561285f565b34801561092c57600080fd5b5061036661286e565b34801561094157600080fd5b5061031e600435602435604435600160a060020a0360643516612874565b34801561096b57600080fd5b5061049e6004356128d7565b34801561098357600080fd5b50610335612909565b34801561099857600080fd5b50610366612918565b3480156109ad57600080fd5b5061031e60043560243560443560643560843560a43561291e565b3480156109d457600080fd5b50610335612a1c565b3480156109e957600080fd5b50610366600435602435604435612a2b565b348015610a0757600080fd5b50610335612d3c565b348015610a1c57600080fd5b50610335612d4b565b61031e600435602435612d5a565b348015610a3f57600080fd5b50610366612ef4565b348015610a5457600080fd5b50610335612efa565b61031e600435602435612f09565b600154600160a060020a031681565b600d5481565b60408051808201909152600a81527f4d6f6e7374657242697400000000000000000000000000000000000000000000602082015281565b60035460a060020a900460ff1615610ace57600080fd5b610ad83382612fcc565b1515610ae357600080fd5b610aed818361305f565b60408051338152600160a060020a038416602082015280820183905290517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360600190a15050565b600054600160a060020a031681565b670de0b6b3a764000081565b60008054600160a060020a0316331480610b785750600354600160a060020a031633145b1515610b8357600080fd5b81905080600160a060020a03166376190f8f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610bc457600080fd5b505af1158015610bd8573d6000803e3d6000fd5b505050506040513d6020811015610bee57600080fd5b50511515610bfb57600080fd5b60058054600160a060020a031916600160a060020a039290921691909117905550565b60006001600860009054906101000a9004600160a060020a0316600160a060020a031663e33640736040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610c7557600080fd5b505af1158015610c89573d6000803e3d6000fd5b505050506040513d6020811015610c9f57600080fd5b505103905090565b6000610cb16149c3565b60008311610cbe57600080fd5b610cc7836130cd565b60c0015163ffffffff1615159392505050565b62278d0081565b600c5481565b600554600160a060020a031681565b60035460a060020a900460ff1615610d0d57600080fd5b600160a060020a0382161515610d2257600080fd5b600160a060020a038216301415610d3857600080fd5b610d42338261319e565b1515610d4d57600080fd5b610d578382612fcc565b1515610d6257600080fd5b610d6d83838361320a565b505050565b60008054600160a060020a0316331480610d965750600354600160a060020a031633145b1515610da157600080fd5b81905080600160a060020a031663f2a736946040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610de257600080fd5b505af1158015610df6573d6000803e3d6000fd5b505050506040513d6020811015610e0c57600080fd5b50511515610e1957600080fd5b600a8054600160a060020a031916600160a060020a039290921691909117905550565b600054600160a060020a0316331480610e5f5750600354600160a060020a031633145b1515610e6a57600080fd5b600160a060020a0381161515610e7f57600080fd5b60008054600160a060020a031916600160a060020a0392909216919091179055565b600054600160a060020a0316331480610ec45750600354600160a060020a031633145b1515610ecf57600080fd5b600160a060020a0381161515610ee457600080fd5b60028054600160a060020a031916600160a060020a0392909216919091179055565b67016345785d8a000081565b60035460a060020a900460ff1615610f2957600080fd5b610f333385612fcc565b1515610f3e57600080fd5b610f4784610ca7565b15610f5157600080fd5b600454610f68908590600160a060020a031661305f565b60048054604080517f27ebe40a00000000000000000000000000000000000000000000000000000000815292830187905260248301869052604483018590526064830184905233608484015251600160a060020a03909116916327ebe40a9160a480830192600092919082900301818387803b158015610fe757600080fd5b505af1158015610ffb573d6000803e3d6000fd5b5050505050505050565b600054600160a060020a03163314806110285750600354600160a060020a031633145b151561103357600080fd5b60035460a060020a900460ff16151561104b57600080fd5b600454600160a060020a0316151561106257600080fd5b600554600160a060020a0316151561107957600080fd5b600754600160a060020a0316151561109057600080fd5b600654600160a060020a031615156110a757600080fd5b600a54600160a060020a031615156110be57600080fd5b600854600160a060020a031615156110d557600080fd5b600954600160a060020a031615156110ec57600080fd5b600f54600160a060020a03161561110257600080fd5b61110a613737565b565b60008054600160a060020a03163314806111305750600354600160a060020a031633145b151561113b57600080fd5b81905080600160a060020a0316633ab7f3b66040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561117c57600080fd5b505af1158015611190573d6000803e3d6000fd5b505050506040513d60208110156111a657600080fd5b505115156111b357600080fd5b60098054600160a060020a031916600160a060020a039290921691909117905550565b60006111e06149c3565b6111e86149c3565b600085116111f557600080fd5b6000841161120257600080fd5b61120b856130cd565b9150611216846130cd565b90506112248286838761379d565b8015611235575061123584866138c7565b95945050505050565b6000808080861161124e57600080fd5b6000851161125b57600080fd5b6000841161126857600080fd5b600091505b600582101561135657604080517f5beb53cd00000000000000000000000000000000000000000000000000000000815260048101889052602084810260ff16602483015260448201819052915173c5483c323e5317b950b875bd6d5f21f63673bfcd92635beb53cd9260648082019391829003018186803b1580156112f157600080fd5b505af4158015611305573d6000803e3d6000fd5b505050506040513d602081101561131b57600080fd5b505190506113293382612fcc565b151561133457600080fd5b60065461134b908290600160a060020a031661305f565b60019091019061126d565b600654604080517f5ddd7e410000000000000000000000000000000000000000000000000000000081523360048201526024810189905260448101889052606481018790529051600160a060020a0390921691635ddd7e41913491608480830192602092919082900301818588803b1580156113d157600080fd5b505af11580156113e5573d6000803e3d6000fd5b50505050506040513d60208110156113fc57600080fd5b50519695505050505050565b60035460a060020a900460ff161561141f57600080fd5b6114293385612fcc565b151561143457600080fd5b61143d846128d7565b151561144857600080fd5b60055461145f908590600160a060020a031661305f565b600554604080517f27ebe40a000000000000000000000000000000000000000000000000000000008152600481018790526024810186905260448101859052606481018490523360848201529051600160a060020a03909216916327ebe40a9160a48082019260009290919082900301818387803b158015610fe757600080fd5b600254600160a060020a031633146114f757600080fd5b600b55565b60035460a060020a900460ff161561151357600080fd5b61151d3382612fcc565b151561152857600080fd5b600854604080517ff4363bec00000000000000000000000000000000000000000000000000000000815260048101849052600160a060020a0385811660248301529151919092169163f4363bec91604480830192600092919082900301818387803b15801561159657600080fd5b505af11580156115aa573d6000803e3d6000fd5b505050505050565b600054600160a060020a03163314806115d55750600354600160a060020a031633145b15156115e057600080fd5b600160a060020a03811615156115f557600080fd5b60018054600160a060020a031916600160a060020a0392909216919091179055565b600254600160a060020a031633148061163a5750600054600160a060020a031633145b8061164f5750600154600160a060020a031633145b806116645750600354600160a060020a031633145b151561166f57600080fd5b60048054604080517f5fd8c7100000000000000000000000000000000000000000000000000000000081529051600160a060020a0390921692635fd8c71092828201926000929082900301818387803b1580156116cb57600080fd5b505af11580156116df573d6000803e3d6000fd5b50505050600560009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b15801561173657600080fd5b505af115801561174a573d6000803e3d6000fd5b50505050600660009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b1580156117a157600080fd5b505af11580156117b5573d6000803e3d6000fd5b50505050600760009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b15801561180c57600080fd5b505af1158015611820573d6000803e3d6000fd5b50505050565b600254600160a060020a0316331461183d57600080fd5b600c55565b60035460a060020a900460ff1681565b6001546000908190600160a060020a0316331461186e57600080fd5b600b54600854604080517fc7e3ff4b000000000000000000000000000000000000000000000000000000008152905130319550600160a060020a039092169163c7e3ff4b916004808201926020929091908290030181600087803b1580156118d557600080fd5b505af11580156118e9573d6000803e3d6000fd5b505050506040513d60208110156118ff57600080fd5b50516001010290508082111561194a57600154604051600160a060020a039091169082840380156108fc02916000818181858888f19350505050158015610d6d573d6000803e3d6000fd5b5050565b6008546040805160e260020a632b52d563028152600481018490529051600092600160a060020a03169163ad4b558c91602480830192602092919082900301818787803b15801561199e57600080fd5b505af11580156119b2573d6000803e3d6000fd5b505050506040513d60208110156119c857600080fd5b50519050600160a060020a03811615156119e157600080fd5b919050565b61afc881565b600f54600160a060020a031681565b60008054600160a060020a0316331480611a1f5750600354600160a060020a031633145b1515611a2a57600080fd5b81905080600160a060020a03166385b861886040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611a6b57600080fd5b505af1158015611a7f573d6000803e3d6000fd5b505050506040513d6020811015611a9557600080fd5b50511515611aa257600080fd5b60048054600160a060020a031916600160a060020a039290921691909117905550565b600854604080517fcec21acb000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301529151600093929092169163cec21acb9160248082019260209290919082900301818787803b158015611b3057600080fd5b505af1158015611b44573d6000803e3d6000fd5b505050506040513d6020811015611b5a57600080fd5b505192915050565b600054600160a060020a0316331480611b855750600354600160a060020a031633145b1515611b9057600080fd5b60035460a060020a900460ff161515611ba857600080fd5b600f8054600160a060020a038316600160a060020a0319909116811790915560408051918252517f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa4461993059181900360200190a150565b60008054600160a060020a0316331480611c205750600354600160a060020a031633145b1515611c2b57600080fd5b81905080600160a060020a031663d86e95976040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611c6c57600080fd5b505af1158015611c80573d6000803e3d6000fd5b505050506040513d6020811015611c9657600080fd5b50511515611ca357600080fd5b60088054600160a060020a031916600160a060020a039290921691909117905550565b60008054600160a060020a0316331480611cea5750600354600160a060020a031633145b1515611cf557600080fd5b81905080600160a060020a031663e3b3f5706040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611d3657600080fd5b505af1158015611d4a573d6000803e3d6000fd5b505050506040513d6020811015611d6057600080fd5b50511515611d6d57600080fd5b60078054600160a060020a031916600160a060020a039290921691909117905550565b600254600160a060020a0316331480611db35750600054600160a060020a031633145b80611dc85750600154600160a060020a031633145b80611ddd5750600354600160a060020a031633145b1515611de857600080fd5b60035460a060020a900460ff1615611dff57600080fd5b6003805474ff0000000000000000000000000000000000000000191660a060020a179055565b6060600060606000806000611e3987611ac5565b9450841515611e58576040805160008152602081019091529550611f58565b84604051908082528060200260200182016040528015611e82578160200160208202803883390190505b509350611e8d610c1e565b925060009150600190505b828111611f54576008546040805160e260020a632b52d563028152600481018490529051600160a060020a03808b1693169163ad4b558c9160248083019260209291908290030181600087803b158015611ef157600080fd5b505af1158015611f05573d6000803e3d6000fd5b505050506040513d6020811015611f1b57600080fd5b5051600160a060020a03161415611f4c57808483815181101515611f3b57fe5b602090810290910101526001909101905b600101611e98565b8395505b5050505050919050565b6000611f6c6149c3565b6000611f766149c3565b600080600080600080600360149054906101000a900460ff16151515611f9b57600080fd5b611fa48b6130cd565b602081015190995067ffffffffffffffff161515611fc157600080fd5b611fca89613a88565b1515611fd557600080fd5b8860c0015163ffffffff169750611feb886130cd565b965088604001519550886040015161ffff16876040015161ffff16111561201457866040015195505b600a5489518851604080517f0d9f5aed000000000000000000000000000000000000000000000000000000008152600481019390935260248301919091526000194301604483015251600160a060020a0390921691630d9f5aed916064808201926020929091908290030181600087803b15801561209157600080fd5b505af11580156120a5573d6000803e3d6000fd5b505050506040513d60208110156120bb57600080fd5b5051600a546101008b810151908a0151604080517f10a624b000000000000000000000000000000000000000000000000000000000815267ffffffffffffffff93841660048201529290911660248301526000194301604483015251929750600160a060020a03909116916310a624b0916064808201926020929091908290030181600087803b15801561214e57600080fd5b505af1158015612162573d6000803e3d6000fd5b505050506040513d602081101561217857600080fd5b50516008546040805160e260020a632b52d563028152600481018f90529051929650600160a060020a039091169163ad4b558c916024808201926020929091908290030181600087803b1580156121ce57600080fd5b505af11580156121e2573d6000803e3d6000fd5b505050506040513d60208110156121f857600080fd5b505160c08a0151909350612220908c9063ffffffff1661ffff60018a01168888600089613ab9565b600854604080517ffaa5bdfb000000000000000000000000000000000000000000000000000000008152600481018f90526000602482018190529151939550600160a060020a039092169263faa5bdfb92604480820193929182900301818387803b15801561228e57600080fd5b505af11580156122a2573d6000803e3d6000fd5b50505050600860009054906101000a9004600160a060020a0316600160a060020a031663c7e3ff4b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156122f957600080fd5b505af115801561230d573d6000803e3d6000fd5b505050506040513d602081101561232357600080fd5b5051600854604080517f745d8e7c000000000000000000000000000000000000000000000000000000008152600019840160048201529051929350600160a060020a039091169163745d8e7c9160248082019260009290919082900301818387803b15801561239157600080fd5b505af11580156123a5573d6000803e3d6000fd5b5050600b5460405133935081156108fc0292506000818181858888f193505050501580156123d7573d6000803e3d6000fd5b50909a9950505050505050505050565b60408051808201909152600281527f4d42000000000000000000000000000000000000000000000000000000000000602082015281565b60008054600160a060020a03163314806124425750600354600160a060020a031633145b151561244d57600080fd5b81905080600160a060020a0316630c61ad4e6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561248e57600080fd5b505af11580156124a2573d6000803e3d6000fd5b505050506040513d60208110156124b857600080fd5b505115156124c557600080fd5b60068054600160a060020a031916600160a060020a039290921691909117905550565b600854604080517f1df256f700000000000000000000000000000000000000000000000000000000815260048101859052905160009283928392600160a060020a0390921691631df256f79160248082019260609290919082900301818787803b15801561255557600080fd5b505af1158015612569573d6000803e3d6000fd5b505050506040513d606081101561257f57600080fd5b508051602082015160409283015160075484517fbde25aa0000000000000000000000000000000000000000000000000000000008152336004820152602481018a905260448101859052606481018490526084810183905294519397509195509350600160a060020a03169163bde25aa091349160a48082019260609290919082900301818588803b15801561261457600080fd5b505af1158015612628573d6000803e3d6000fd5b50505050506040513d606081101561263f57600080fd5b508051602082015160409283015160085484517f7ab37399000000000000000000000000000000000000000000000000000000008152600481018b905260248101859052604481018490526064810183905294519397509195509350600160a060020a031691637ab3739991608480830192600092919082900301818387803b1580156126cb57600080fd5b505af11580156126df573d6000803e3d6000fd5b5050604080518881526000602082015281517f9768e5862fdc96c4d2fb8e17c81799282f5affe1a5be5fcdfd07215279b4efb59450908190039091019150a15050505050565b600654604080517f8e7339510000000000000000000000000000000000000000000000000000000081523360048201526024810186905260448101859052606481018490529051600092600160a060020a031691638e73395191608480830192602092919082900301818787803b15801561279f57600080fd5b505af11580156127b3573d6000803e3d6000fd5b505050506040513d60208110156127c957600080fd5b5051949350505050565b600754600160a060020a031681565b60035460a060020a900460ff16156127f957600080fd5b600160a060020a038216151561280e57600080fd5b600160a060020a03821630141561282457600080fd5b600454600160a060020a038381169116141561283f57600080fd5b6128493382612fcc565b151561285457600080fd5b61194a33838361320a565b600254600160a060020a031681565b600b5481565b600254600090600160a060020a0316331461288e57600080fd5b5080600160a060020a03811615156128ae5750600254600160a060020a03165b600d546103e8116128be57600080fd5b600d805460010190556115aa6000808088888887613ab9565b60006128e16149c3565b600083116128ee57600080fd5b6128f7836130cd565b905061290281613cf0565b9392505050565b600854600160a060020a031681565b6103e881565b600254600090600160a060020a0316331461293857600080fd5b600e5461afc81161294857600080fd5b61295960008060008a8a8a30613ab9565b600454909150612973908290600160a060020a031661305f565b60048054604080517f27ebe40a00000000000000000000000000000000000000000000000000000000815292830184905260248301879052604483018690526064830185905230608484015251600160a060020a03909116916327ebe40a9160a480830192600092919082900301818387803b1580156129f257600080fd5b505af1158015612a06573d6000803e3d6000fd5b5050600e80546001019055505050505050505050565b600954600160a060020a031681565b600080600080612a39614a47565b600080612a446149c3565b600654604080517f0b0b39ee000000000000000000000000000000000000000000000000000000008152336004820152602481018e9052604481018d9052606481018c905290516000928392600160a060020a0390911691630b0b39ee9160848082019260609290919082900301818787803b158015612ac357600080fd5b505af1158015612ad7573d6000803e3d6000fd5b505050506040513d6060811015612aed57600080fd5b5080516020820151604090920151909a5090985096506000871015612b1157600080fd5b600094505b6008851015612be557604080517f5beb53cd000000000000000000000000000000000000000000000000000000008152600481018b9052602087810260ff16602483015260448201819052915173c5483c323e5317b950b875bd6d5f21f63673bfcd92635beb53cd9260648082019391829003018186803b158015612b9a57600080fd5b505af4158015612bae573d6000803e3d6000fd5b505050506040513d6020811015612bc457600080fd5b50519350838686600a8110612bd557fe5b6020020152600190940193612b16565b600094505b6002851015612cbc57604080517f5beb53cd000000000000000000000000000000000000000000000000000000008152600481018a9052602087810260ff16602483015260448201819052915173c5483c323e5317b950b875bd6d5f21f63673bfcd92635beb53cd9260648082019391829003018186803b158015612c6e57600080fd5b505af4158015612c82573d6000803e3d6000fd5b505050506040513d6020811015612c9857600080fd5b50519350838660088701600a8110612cac57fe5b6020020152600190940193612bea565b600094505b600a851015612d2c578585600a8110612cd657fe5b60200201519350612ce6846130cd565b9250826101e0015160010160ff16915060009050600a82101515612d0c57506000905060015b60ff82166101e0840152612d21848483613d3c565b600190940193612cc1565b5050505050505050509392505050565b600654600160a060020a031681565b600454600160a060020a031681565b60035460009060a060020a900460ff1615612d7457600080fd5b612d7e3383612fcc565b1515612d8957600080fd5b612d92826128d7565b1515612d9d57600080fd5b612da78284613f41565b1515612db257600080fd5b600554604080517fc55d0f56000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a039092169163c55d0f56916024808201926020929091908290030181600087803b158015612e1957600080fd5b505af1158015612e2d573d6000803e3d6000fd5b505050506040513d6020811015612e4357600080fd5b5051600b549091508101341015612e5957600080fd5b600554600b54604080517f454a2ab3000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a039093169263454a2ab39234039160248082019260009290919082900301818588803b158015612ec557600080fd5b505af1158015612ed9573d6000803e3d6000fd5b5050505050610d6d8263ffffffff168463ffffffff16613f75565b600e5481565b600a54600160a060020a031681565b612f116149c3565b612f196149c3565b60035460a060020a900460ff1615612f3057600080fd5b600c54600b5401341015612f4357600080fd5b612f4d3385612fcc565b1515612f5857600080fd5b612f6283856138c7565b1515612f6d57600080fd5b612f76846130cd565b9150612f8182613cf0565b1515612f8c57600080fd5b612f95836130cd565b9050612fa081613cf0565b1515612fab57600080fd5b612fb78285838661379d565b1515612fc257600080fd5b6118208484613f75565b6008546040805160e260020a632b52d563028152600481018490529051600092600160a060020a038087169391169163ad4b558c9160248082019260209290919082900301818887803b15801561302257600080fd5b505af1158015613036573d6000803e3d6000fd5b505050506040513d602081101561304c57600080fd5b5051600160a060020a0316149392505050565b600854604080517f3270896600000000000000000000000000000000000000000000000000000000815260048101859052600160a060020a03848116602483015291519190921691633270896691604480830192600092919082900301818387803b15801561159657600080fd5b6130d56149c3565b60008060006130e26149c3565b600854604080517f1df256f7000000000000000000000000000000000000000000000000000000008152600481018990529051600160a060020a0390921691631df256f7916024808201926060929091908290030181600087803b15801561314957600080fd5b505af115801561315d573d6000803e3d6000fd5b505050506040513d606081101561317357600080fd5b50805160208201516040909201519095509093509150613194848484614329565b9695505050505050565b600854604080517f7d55aeea000000000000000000000000000000000000000000000000000000008152600481018490529051600092600160a060020a0380871693911691637d55aeea9160248082019260209290919082900301818887803b15801561302257600080fd5b60006132146149c3565b600854604080517fcec21acb000000000000000000000000000000000000000000000000000000008152600160a060020a0387811660048301529151919092169163cec21acb9160248083019260209291908290030181600087803b15801561327c57600080fd5b505af1158015613290573d6000803e3d6000fd5b505050506040513d60208110156132a657600080fd5b5051600854604080517f638a4e7f000000000000000000000000000000000000000000000000000000008152600160a060020a038881166004830152600185016024830152915193955091169163638a4e7f9160448082019260009290919082900301818387803b15801561331a57600080fd5b505af115801561332e573d6000803e3d6000fd5b5050600854604080517f40a401d000000000000000000000000000000000000000000000000000000000815260048101889052600160a060020a03898116602483015291519190921693506340a401d09250604480830192600092919082900301818387803b1580156133a057600080fd5b505af11580156133b4573d6000803e3d6000fd5b50505050600160a060020a0385161561356957600854604080517fcec21acb000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301529151919092169163cec21acb9160248083019260209291908290030181600087803b15801561342f57600080fd5b505af1158015613443573d6000803e3d6000fd5b505050506040513d602081101561345957600080fd5b5051600854604080517f638a4e7f000000000000000000000000000000000000000000000000000000008152600160a060020a03898116600483015260001985016024830152915193955091169163638a4e7f9160448082019260009290919082900301818387803b1580156134ce57600080fd5b505af11580156134e2573d6000803e3d6000fd5b5050600854604080517f32708966000000000000000000000000000000000000000000000000000000008152600481018890526000602482018190529151600160a060020a039093169450633270896693506044808201939182900301818387803b15801561355057600080fd5b505af1158015613564573d6000803e3d6000fd5b505050505b600454600160a060020a03868116911614156136e657613588836130cd565b905080610160015160ff16600014156136e65760085460e0820151600954610120840151604080517f6989767c00000000000000000000000000000000000000000000000000000000815260ff909216600483015251600160a060020a039485169463259fb3609489949093911691636989767c916024808201926020929091908290030181600087803b15801561361f57600080fd5b505af1158015613633573d6000803e3d6000fd5b505050506040513d602081101561364957600080fd5b50516101208601516101408701516040805163ffffffff88811660e060020a028252600482019790975261ffff959095166024860152949092164290810167ffffffffffffffff166044850152606484015260ff90811660848401521660a4820152905160c480830192600092919082900301818387803b1580156136cd57600080fd5b505af11580156136e1573d6000803e3d6000fd5b505050505b60408051600160a060020a0380881682528616602082015280820185905290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360600190a15050505050565b600054600160a060020a031633148061375a5750600354600160a060020a031633145b151561376557600080fd5b60035460a060020a900460ff16151561377d57600080fd5b6003805474ff000000000000000000000000000000000000000019169055565b6000818414156137af575060006138bf565b81856080015163ffffffff1614806137d05750818560a0015163ffffffff16145b156137dd575060006138bf565b83836080015163ffffffff1614806137fe5750838360a0015163ffffffff16145b1561380b575060006138bf565b608083015163ffffffff16158061382a5750608085015163ffffffff16155b15613837575060016138bf565b846080015163ffffffff16836080015163ffffffff16148061386c57508460a0015163ffffffff16836080015163ffffffff16145b15613879575060006138bf565b846080015163ffffffff168360a0015163ffffffff1614806138ae57508460a0015163ffffffff168360a0015163ffffffff16145b156138bb575060006138bf565b5060015b949350505050565b6008546040805160e260020a632b52d56302815260048101849052905160009283928392600160a060020a039092169163ad4b558c9160248082019260209290919082900301818787803b15801561391e57600080fd5b505af1158015613932573d6000803e3d6000fd5b505050506040513d602081101561394857600080fd5b50516008546040805160e260020a632b52d563028152600481018990529051929450600160a060020a039091169163ad4b558c916024808201926020929091908290030181600087803b15801561399e57600080fd5b505af11580156139b2573d6000803e3d6000fd5b505050506040513d60208110156139c857600080fd5b50519050600160a060020a0382811690821614806112355750600854604080517f46116e6f000000000000000000000000000000000000000000000000000000008152600481018890529051600160a060020a038086169316916346116e6f9160248083019260209291908290030181600087803b158015613a4957600080fd5b505af1158015613a5d573d6000803e3d6000fd5b505050506040513d6020811015613a7357600080fd5b5051600160a060020a03161495945050505050565b60008160c0015163ffffffff16600014158015613ab3575042826060015167ffffffffffffffff1611155b92915050565b6000613ac36149c3565b600080808063ffffffff8d168d14613ada57600080fd5b63ffffffff8c168c14613aec57600080fd5b61ffff8b168b14613afc57600080fd5b610200604051908101604052808b81526020014267ffffffffffffffff1681526020018c61ffff168152602001600067ffffffffffffffff1681526020018e63ffffffff1681526020018d63ffffffff168152602001600063ffffffff168152602001600061ffff1681526020018a67ffffffffffffffff168152602001600060ff168152602001600060ff1681526020018960ff168152602001600060ff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600060ff168152509450613bd685614529565b613bdf856147d8565b600854604080517f6b40d1900000000000000000000000000000000000000000000000000000000081526004810186905260248101859052604481018490529051949850929650909450600160a060020a031691636b40d190916064808201926020929091908290030181600087803b158015613c5b57600080fd5b505af1158015613c6f573d6000803e3d6000fd5b505050506040513d6020811015613c8557600080fd5b505160408051600160a060020a038a168152602081018390528082018d905290519192507f393ccba6479926a7c4a6471a3b4584229e2df48a1858c8caf57680927dced5ff919081900360600190a1613ce06000888361320a565b9c9b505050505050505050505050565b60008160c0015163ffffffff166000148015613ab357504267ffffffffffffffff16826060015167ffffffffffffffff1611158015613ab35750506101600151600160ff909116101590565b60e0820151600954604080517fc7030cbc00000000000000000000000000000000000000000000000000000000815261ffff909316600484018190529051909260009283924292600160a060020a039092169163c7030cbc91602480830192602092919082900301818887803b158015613db557600080fd5b505af1158015613dc9573d6000803e3d6000fd5b505050506040513d6020811015613ddf57600080fd5b505160e087015167ffffffffffffffff63ffffffff9092169290920116925061ffff1690506000841115613e9a57600960009054906101000a9004600160a060020a0316600160a060020a031663826e8d116040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015613e6057600080fd5b505af1158015613e74573d6000803e3d6000fd5b505050506040513d6020811015613e8a57600080fd5b5051600182011015613e9a576001015b600854604080517f259fb36000000000000000000000000000000000000000000000000000000000815260048101899052602481018490526044810185905242606482015260006084820181905260a482018790529151600160a060020a039093169263259fb3609260c48084019391929182900301818387803b158015613f2157600080fd5b505af1158015613f35573d6000803e3d6000fd5b50505050505050505050565b6000613f4b6149c3565b613f536149c3565b613f5c856130cd565b9150613f67846130cd565b90506112358286838761379d565b613f7d6149c3565b613f856149c3565b6000613f90846130cd565b9250613f9b856130cd565b600854604080517ffaa5bdfb00000000000000000000000000000000000000000000000000000000815260048101899052602481018890529051929450600160a060020a039091169163faa5bdfb9160448082019260009290919082900301818387803b15801561400b57600080fd5b505af115801561401f573d6000803e3d6000fd5b5050505061402f84846001613d3c565b61403b85836001613d3c565b600854604080517ff4363bec000000000000000000000000000000000000000000000000000000008152600481018890526000602482018190529151600160a060020a039093169263f4363bec9260448084019391929182900301818387803b1580156140a757600080fd5b505af11580156140bb573d6000803e3d6000fd5b5050600854604080517ff4363bec000000000000000000000000000000000000000000000000000000008152600481018990526000602482018190529151600160a060020a03909316945063f4363bec93506044808201939182900301818387803b15801561412957600080fd5b505af115801561413d573d6000803e3d6000fd5b50505050600860009054906101000a9004600160a060020a0316600160a060020a031663c7e3ff4b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561419457600080fd5b505af11580156141a8573d6000803e3d6000fd5b505050506040513d60208110156141be57600080fd5b5051600854604080517f745d8e7c0000000000000000000000000000000000000000000000000000000081526001840160048201529051929350600160a060020a039091169163745d8e7c9160248082019260009290919082900301818387803b15801561422b57600080fd5b505af115801561423f573d6000803e3d6000fd5b50506008546040805160e260020a632b52d563028152600481018a905290517f241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b809450600160a060020a03909216925063ad4b558c9160248083019260209291908290030181600087803b1580156142b557600080fd5b505af11580156142c9573d6000803e3d6000fd5b505050506040513d60208110156142df57600080fd5b505160608085015160408051600160a060020a039094168452602084018a905283810189905267ffffffffffffffff90911691830191909152519081900360800190a15050505050565b6143316149c3565b506040805161020081018252600060208201819052818301819052606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820181905261018082018190526101a082018190526101c082018190526101e0820181905285825290916143bf918591614978565b67ffffffffffffffff1660608201526143da83604080614978565b67ffffffffffffffff166101a08201526143f78360806040614978565b67ffffffffffffffff166101c08201526144148360c06040614978565b67ffffffffffffffff1660208201526144308260006010614978565b61ffff1660408201526144468260106020614978565b63ffffffff16608082015261445e8260306020614978565b63ffffffff1660a08201526144768260506020614978565b63ffffffff1660c082015261448e8260706010614978565b61ffff1660e08201526144a48260806040614978565b67ffffffffffffffff166101008201526144c18260c06008614978565b60ff166101208201526144d78260c86008614978565b60ff166101408201526144ed8260d06008614978565b60ff166101608201526145038260d86008614978565b60ff166101808201526145198260e06008614978565b60ff166101e08201529392505050565b6000806002836040015161ffff1681151561454057fe5b049150600d8261ffff16111561455557600d91505b61ffff821660e084015261016083015160ff161515610d6d57826040015161ffff169050600960009054906101000a9004600160a060020a0316600160a060020a0316635a4eae026040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156145cc57600080fd5b505af11580156145e0573d6000803e3d6000fd5b505050506040513d60208110156145f657600080fd5b505181111561468157600960009054906101000a9004600160a060020a0316600160a060020a0316635a4eae026040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561465257600080fd5b505af1158015614666573d6000803e3d6000fd5b505050506040513d602081101561467c57600080fd5b505190505b600954604080517ff63e842c000000000000000000000000000000000000000000000000000000008152600481018490529051600160a060020a039092169163f63e842c916024808201926020929091908290030181600087803b1580156146e857600080fd5b505af11580156146fc573d6000803e3d6000fd5b505050506040513d602081101561471257600080fd5b505160ff166101208401819052600954604080517f6989767c000000000000000000000000000000000000000000000000000000008152600481019390935251600160a060020a0390911691636989767c9160248083019260209291908290030181600087803b15801561478557600080fd5b505af1158015614799573d6000803e3d6000fd5b505050506040513d60208110156147af57600080fd5b505167ffffffffffffffff4263ffffffff909216820181166060860152166101c0840152505050565b8051606082015160009081906147fc90829067ffffffffffffffff166040826149a3565b915061481a82856101a0015167ffffffffffffffff166040806149a3565b915061483982856101c0015167ffffffffffffffff16604060806149a3565b915061485782856020015167ffffffffffffffff16604060c06149a3565b91506000905061487381856040015161ffff16601060006149a3565b905061488d81856080015163ffffffff16602060106149a3565b90506148a7818560a0015163ffffffff16602060306149a3565b90506148c1818560c0015163ffffffff16602060506149a3565b90506148d9818560e0015161ffff16601060706149a3565b90506148f88185610100015167ffffffffffffffff16604060806149a3565b90506149108185610120015160ff16600860c06149a3565b90506149288185610140015160ff16600860c86149a3565b90506149408185610160015160ff16600860d06149a3565b90506149588185610180015160ff16600860d86149a3565b905061497081856101e0015160ff16600860e06149a3565b929491935050565b6000808360020a60018460020a030290508360020a81861681151561499957fe5b0495945050505050565b600291820a6000199081019384169190920a908102920218919091161790565b6040805161020081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081019190915290565b61014060405190810160405280600a9060208202803883395091929150505600a165627a7a72305820d311a6408780c904edc1da1041b2b593275b144f01af6d2de9a2d3ecd566437c0029
Verified Source Code Partial Match
Compiler: v0.4.24+commit.e67f0147
EVM: byzantium
Optimization: Yes (200 runs)
MonsterCore.sol 1722 lines
pragma solidity ^0.4.23;
/// @title A facet of MonsterCore that manages special access privileges.
/// @dev See the MonsterCore contract documentation to understand how the various contract facets are arranged.
contract MonsterAccessControl {
// This facet controls access control for MonsterBit. There are four roles managed here:
//
// - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart
// contracts. It is also the only role that can unpause the smart contract. It is initially
// set to the address that created the smart contract in the MonsterCore constructor.
//
// - The CFO: The CFO can withdraw funds from MonsterCore and its auction contracts.
//
// - The COO: The COO can release gen0 monsters to auction, and mint promo monsters.
//
// It should be noted that these roles are distinct without overlap in their access abilities, the
// abilities listed for each role above are exhaustive. In particular, while the CEO can assign any
// address to any role, the CEO address itself doesn't have the ability to act in those roles. This
// restriction is intentional so that we aren't tempted to use the CEO address frequently out of
// convenience. The less we use an address, the less likely it is that we somehow compromise the
// account.
/// @dev Emited when contract is upgraded - See README.md for updgrade plan
event ContractUpgrade(address newContract);
// The addresses of the accounts (or contracts) that can execute actions within each roles.
address public ceoAddress;
address public cfoAddress;
address public cooAddress;
address ceoBackupAddress;
// @dev Keeps track whether the contract is paused. When that is true, most actions are blocked
bool public paused = false;
/// @dev Access modifier for CEO-only functionality
modifier onlyCEO() {
require(msg.sender == ceoAddress || msg.sender == ceoBackupAddress);
_;
}
/// @dev Access modifier for CFO-only functionality
modifier onlyCFO() {
require(msg.sender == cfoAddress);
_;
}
/// @dev Access modifier for COO-only functionality
modifier onlyCOO() {
require(msg.sender == cooAddress);
_;
}
modifier onlyCLevel() {
require(
msg.sender == cooAddress ||
msg.sender == ceoAddress ||
msg.sender == cfoAddress ||
msg.sender == ceoBackupAddress
);
_;
}
/// @dev Assigns a new address to act as the CEO. Only available to the current CEO.
/// @param _newCEO The address of the new CEO
function setCEO(address _newCEO) external onlyCEO {
require(_newCEO != address(0));
ceoAddress = _newCEO;
}
/// @dev Assigns a new address to act as the CFO. Only available to the current CEO.
/// @param _newCFO The address of the new CFO
function setCFO(address _newCFO) external onlyCEO {
require(_newCFO != address(0));
cfoAddress = _newCFO;
}
/// @dev Assigns a new address to act as the COO. Only available to the current CEO.
/// @param _newCOO The address of the new COO
function setCOO(address _newCOO) external onlyCEO {
require(_newCOO != address(0));
cooAddress = _newCOO;
}
/*** Pausable functionality adapted from OpenZeppelin ***/
/// @dev Modifier to allow actions only when the contract IS NOT paused
modifier whenNotPaused() {
require(!paused);
_;
}
/// @dev Modifier to allow actions only when the contract IS paused
modifier whenPaused {
require(paused);
_;
}
/// @dev Called by any "C-level" role to pause the contract. Used only when
/// a bug or exploit is detected and we need to limit damage.
function pause() external onlyCLevel whenNotPaused {
paused = true;
}
/// @dev Unpauses the smart contract. Can only be called by the CEO, since
/// one reason we may pause the contract is when CFO or COO accounts are
/// compromised.
/// @notice This is public rather than external so it can be called by
/// derived contracts.
function unpause() public onlyCEO whenPaused {
// can't unpause if contract was upgraded
paused = false;
}
}
interface SaleClockAuction {
function isSaleClockAuction() external view returns (bool);
function createAuction(uint, uint, uint, uint, address) external;
function withdrawBalance() external;
}
interface SiringClockAuction {
function isSiringClockAuction() external view returns (bool);
function createAuction(uint, uint, uint, uint, address) external;
function withdrawBalance() external;
function getCurrentPrice(uint256) external view returns (uint256);
function bid(uint256) external payable;
}
interface MonsterBattles {
function isBattleContract() external view returns (bool);
function prepareForBattle(address, uint, uint, uint) external payable returns(uint);
function withdrawFromBattle(address, uint, uint, uint) external returns(uint);
function finishBattle(address, uint, uint, uint) external returns(uint, uint, uint);
function withdrawBalance() external;
}
interface MonsterFood {
function isMonsterFood() external view returns (bool);
function feedMonster(address, uint, uint, uint, uint) external payable returns(uint, uint, uint);
function withdrawBalance() external;
}
// interface MonsterStorage {
// function isMonsterStorage() external view returns (bool);
// function ownershipTokenCount(address) external view returns (uint);
// function setOwnershipTokenCount(address, uint) external;
// function setActionCooldown(uint, uint, uint, uint, uint, uint) external;
// function createMonster(uint, uint, uint) external returns (uint);
// function getMonsterBits(uint) external view returns(uint, uint, uint);
// function monsterIndexToOwner(uint256) external view returns(address);
// function setMonsterIndexToOwner(uint, address) external;
// function monsterIndexToApproved(uint256) external view returns(address);
// function setMonsterIndexToApproved(uint, address) external;
// function getMonstersCount() external view returns(uint);
// function sireAllowedToAddress(uint256) external view returns(address);
// function setSireAllowedToAddress(uint, address) external;
// function setSiringWith(uint, uint) external;
// }
interface MonsterConstants {
function isMonsterConstants() external view returns (bool);
function actionCooldowns(uint) external view returns (uint32);
function actionCooldownsLength() external view returns(uint);
function growCooldowns(uint) external view returns (uint32);
function genToGrowCdIndex(uint) external view returns (uint8);
function genToGrowCdIndexLength() external view returns(uint);
}
contract MonsterGeneticsInterface {
/// @dev simply a boolean to indicate this is the contract we expect to be
function isMonsterGenetics() public pure returns (bool);
/// @dev given genes of monster 1 & 2, return a genetic combination - may have a random factor
/// @param genesMatron genes of mom
/// @param genesSire genes of sire
/// @return the genes that are supposed to be passed down the child
function mixGenes(uint256 genesMatron, uint256 genesSire, uint256 targetBlock) public view returns (uint256 _result);
function mixBattleGenes(uint256 genesMatron, uint256 genesSire, uint256 targetBlock) public view returns (uint256 _result);
}
library MonsterLib {
//max uint constant for bit operations
uint constant UINT_MAX = uint(2) ** 256 - 1;
function getBits(uint256 source, uint offset, uint count) public pure returns(uint256 bits_)
{
uint256 mask = (uint(2) ** count - 1) * uint(2) ** offset;
return (source & mask) / uint(2) ** offset;
}
function setBits(uint target, uint bits, uint size, uint offset) public pure returns(uint)
{
//ensure bits do not exccess declared size
uint256 truncateMask = uint(2) ** size - 1;
bits = bits & truncateMask;
//shift in place
bits = bits * uint(2) ** offset;
uint clearMask = ((uint(2) ** size - 1) * (uint(2) ** offset)) ^ UINT_MAX;
target = target & clearMask;
target = target | bits;
return target;
}
/// @dev The main Monster struct. Every monster in MonsterBit is represented by a copy
/// of this structure, so great care was taken to ensure that it fits neatly into
/// exactly two 256-bit words. Note that the order of the members in this structure
/// is important because of the byte-packing rules used by Ethereum.
/// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html
struct Monster {
// The Monster's genetic code is packed into these 256-bits, the format is
// sooper-sekret! A monster's genes never change.
uint256 genes;
// The timestamp from the block when this monster came into existence.
uint64 birthTime;
// The "generation number" of this monster. Monsters minted by the CK contract
// for sale are called "gen0" and have a generation number of 0. The
// generation number of all other monsters is the larger of the two generation
// numbers of their parents, plus one.
// (i.e. max(matron.generation, sire.generation) + 1)
uint16 generation;
// The minimum timestamp after which this monster can engage in breeding
// activities again. This same timestamp is used for the pregnancy
// timer (for matrons) as well as the siring cooldown.
uint64 cooldownEndTimestamp;
// The ID of the parents of this monster, set to 0 for gen0 monsters.
// Note that using 32-bit unsigned integers limits us to a "mere"
// 4 billion monsters. This number might seem small until you realize
// that Ethereum currently has a limit of about 500 million
// transactions per year! So, this definitely won't be a problem
// for several years (even as Ethereum learns to scale).
uint32 matronId;
uint32 sireId;
// Set to the ID of the sire monster for matrons that are pregnant,
// zero otherwise. A non-zero value here is how we know a monster
// is pregnant. Used to retrieve the genetic material for the new
// monster when the birth transpires.
uint32 siringWithId;
// Set to the index in the cooldown array (see below) that represents
// the current cooldown duration for this monster. This starts at zero
// for gen0 cats, and is initialized to floor(generation/2) for others.
// Incremented by one for each successful breeding action, regardless
// of whether this monster is acting as matron or sire.
uint16 cooldownIndex;
// Monster genetic code for battle attributes
uint64 battleGenes;
uint8 activeGrowCooldownIndex;
uint8 activeRestCooldownIndex;
uint8 level;
uint8 potionEffect;
uint64 potionExpire;
uint64 cooldownStartTimestamp;
uint8 battleCounter;
}
function encodeMonsterBits(Monster mon) internal pure returns(uint p1, uint p2, uint p3)
{
p1 = mon.genes;
p2 = 0;
p2 = setBits(p2, mon.cooldownEndTimestamp, 64, 0);
p2 = setBits(p2, mon.potionExpire, 64, 64);
p2 = setBits(p2, mon.cooldownStartTimestamp, 64, 128);
p2 = setBits(p2, mon.birthTime, 64, 192);
p3 = 0;
p3 = setBits(p3, mon.generation, 16, 0);
p3 = setBits(p3, mon.matronId, 32, 16);
p3 = setBits(p3, mon.sireId, 32, 48);
p3 = setBits(p3, mon.siringWithId, 32, 80);
p3 = setBits(p3, mon.cooldownIndex, 16, 112);
p3 = setBits(p3, mon.battleGenes, 64, 128);
p3 = setBits(p3, mon.activeGrowCooldownIndex, 8, 192);
p3 = setBits(p3, mon.activeRestCooldownIndex, 8, 200);
p3 = setBits(p3, mon.level, 8, 208);
p3 = setBits(p3, mon.potionEffect, 8, 216);
p3 = setBits(p3, mon.battleCounter, 8, 224);
}
function decodeMonsterBits(uint p1, uint p2, uint p3) internal pure returns(Monster mon)
{
mon = MonsterLib.Monster({
genes: 0,
birthTime: 0,
cooldownEndTimestamp: 0,
matronId: 0,
sireId: 0,
siringWithId: 0,
cooldownIndex: 0,
generation: 0,
battleGenes: 0,
level: 0,
activeGrowCooldownIndex: 0,
activeRestCooldownIndex: 0,
potionEffect: 0,
potionExpire: 0,
cooldownStartTimestamp: 0,
battleCounter: 0
});
mon.genes = p1;
mon.cooldownEndTimestamp = uint64(getBits(p2, 0, 64));
mon.potionExpire = uint64(getBits(p2, 64, 64));
mon.cooldownStartTimestamp = uint64(getBits(p2, 128, 64));
mon.birthTime = uint64(getBits(p2, 192, 64));
mon.generation = uint16(getBits(p3, 0, 16));
mon.matronId = uint32(getBits(p3, 16, 32));
mon.sireId = uint32(getBits(p3, 48, 32));
mon.siringWithId = uint32(getBits(p3, 80, 32));
mon.cooldownIndex = uint16(getBits(p3, 112, 16));
mon.battleGenes = uint64(getBits(p3, 128, 64));
mon.activeGrowCooldownIndex = uint8(getBits(p3, 192, 8));
mon.activeRestCooldownIndex = uint8(getBits(p3, 200, 8));
mon.level = uint8(getBits(p3, 208, 8));
mon.potionEffect = uint8(getBits(p3, 216, 8));
mon.battleCounter = uint8(getBits(p3, 224, 8));
}
}
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
constructor() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
if (newOwner != address(0)) {
owner = newOwner;
}
}
}
contract MonsterStorage is Ownable
{
ERC721 public nonFungibleContract;
bool public isMonsterStorage = true;
constructor(address _nftAddress) public
{
ERC721 candidateContract = ERC721(_nftAddress);
nonFungibleContract = candidateContract;
MonsterLib.Monster memory mon = MonsterLib.decodeMonsterBits(uint(-1), 0, 0);
_createMonster(mon);
monsterIndexToOwner[0] = address(0);
}
function setTokenContract(address _nftAddress) external onlyOwner
{
ERC721 candidateContract = ERC721(_nftAddress);
nonFungibleContract = candidateContract;
}
modifier onlyCore() {
require(msg.sender != address(0) && msg.sender == address(nonFungibleContract));
_;
}
/*** STORAGE ***/
/// @dev An array containing the Monster struct for all Monsters in existence. The ID
/// of each monster is actually an index into this array. Note that ID 0 is a negamonster,
/// the unMonster, the mythical beast that is the parent of all gen0 monsters. A bizarre
/// creature that is both matron and sire... to itself! Has an invalid genetic code.
/// In other words, monster ID 0 is invalid... ;-)
MonsterLib.Monster[] monsters;
uint256 public pregnantMonsters;
function setPregnantMonsters(uint newValue) onlyCore public
{
pregnantMonsters = newValue;
}
function getMonstersCount() public view returns(uint)
{
return monsters.length;
}
/// @dev A mapping from monster IDs to the address that owns them. All monsters have
/// some valid owner address, even gen0 monsters are created with a non-zero owner.
mapping (uint256 => address) public monsterIndexToOwner;
function setMonsterIndexToOwner(uint index, address owner) onlyCore public
{
monsterIndexToOwner[index] = owner;
}
// @dev A mapping from owner address to count of tokens that address owns.
// Used internally inside balanceOf() to resolve ownership count.
mapping (address => uint256) public ownershipTokenCount;
function setOwnershipTokenCount(address owner, uint count) onlyCore public
{
ownershipTokenCount[owner] = count;
}
/// @dev A mapping from MonsterIDs to an address that has been approved to call
/// transferFrom(). Each Monster can only have one approved address for transfer
/// at any time. A zero value means no approval is outstanding.
mapping (uint256 => address) public monsterIndexToApproved;
function setMonsterIndexToApproved(uint index, address approved) onlyCore public
{
if(approved == address(0))
{
delete monsterIndexToApproved[index];
}
else
{
monsterIndexToApproved[index] = approved;
}
}
/// @dev A mapping from MonsterIDs to an address that has been approved to use
/// this monster for siring via breedWith(). Each monster can only have one approved
/// address for siring at any time. A zero value means no approval is outstanding.
mapping (uint256 => address) public sireAllowedToAddress;
function setSireAllowedToAddress(uint index, address allowed) onlyCore public
{
if(allowed == address(0))
{
delete sireAllowedToAddress[index];
}
else
{
sireAllowedToAddress[index] = allowed;
}
}
/// @dev An internal method that creates a new monster and stores it. This
/// method doesn't do any checking and should only be called when the
/// input data is known to be valid. Will generate both a Birth event
/// and a Transfer event.
function createMonster(uint p1, uint p2, uint p3)
onlyCore
public
returns (uint)
{
MonsterLib.Monster memory mon = MonsterLib.decodeMonsterBits(p1, p2, p3);
uint256 newMonsterId = _createMonster(mon);
// It's probably never going to happen, 4 billion monsters is A LOT, but
// let's just be 100% sure we never let this happen.
require(newMonsterId == uint256(uint32(newMonsterId)));
return newMonsterId;
}
function _createMonster(MonsterLib.Monster mon) internal returns(uint)
{
uint256 newMonsterId = monsters.push(mon) - 1;
return newMonsterId;
}
function setLevel(uint monsterId, uint level) onlyCore public
{
MonsterLib.Monster storage mon = monsters[monsterId];
mon.level = uint8(level);
}
function setPotion(uint monsterId, uint potionEffect, uint potionExpire) onlyCore public
{
MonsterLib.Monster storage mon = monsters[monsterId];
mon.potionEffect = uint8(potionEffect);
mon.potionExpire = uint64(potionExpire);
}
function setBattleCounter(uint monsterId, uint battleCounter) onlyCore public
{
MonsterLib.Monster storage mon = monsters[monsterId];
mon.battleCounter = uint8(battleCounter);
}
function setActionCooldown(uint monsterId,
uint cooldownIndex,
uint cooldownEndTimestamp,
uint cooldownStartTimestamp,
uint activeGrowCooldownIndex,
uint activeRestCooldownIndex) onlyCore public
{
MonsterLib.Monster storage mon = monsters[monsterId];
mon.cooldownIndex = uint16(cooldownIndex);
mon.cooldownEndTimestamp = uint64(cooldownEndTimestamp);
mon.cooldownStartTimestamp = uint64(cooldownStartTimestamp);
mon.activeRestCooldownIndex = uint8(activeRestCooldownIndex);
mon.activeGrowCooldownIndex = uint8(activeGrowCooldownIndex);
}
function setSiringWith(uint monsterId, uint siringWithId) onlyCore public
{
MonsterLib.Monster storage mon = monsters[monsterId];
if(siringWithId == 0)
{
delete mon.siringWithId;
}
else
{
mon.siringWithId = uint32(siringWithId);
}
}
function getMonsterBits(uint monsterId) public view returns(uint p1, uint p2, uint p3)
{
MonsterLib.Monster storage mon = monsters[monsterId];
(p1, p2, p3) = MonsterLib.encodeMonsterBits(mon);
}
function setMonsterBits(uint monsterId, uint p1, uint p2, uint p3) onlyCore public
{
MonsterLib.Monster storage mon = monsters[monsterId];
MonsterLib.Monster memory mon2 = MonsterLib.decodeMonsterBits(p1, p2, p3);
mon.cooldownIndex = mon2.cooldownIndex;
mon.siringWithId = mon2.siringWithId;
mon.activeGrowCooldownIndex = mon2.activeGrowCooldownIndex;
mon.activeRestCooldownIndex = mon2.activeRestCooldownIndex;
mon.level = mon2.level;
mon.potionEffect = mon2.potionEffect;
mon.cooldownEndTimestamp = mon2.cooldownEndTimestamp;
mon.potionExpire = mon2.potionExpire;
mon.cooldownStartTimestamp = mon2.cooldownStartTimestamp;
mon.battleCounter = mon2.battleCounter;
}
function setMonsterBitsFull(uint monsterId, uint p1, uint p2, uint p3) onlyCore public
{
MonsterLib.Monster storage mon = monsters[monsterId];
MonsterLib.Monster memory mon2 = MonsterLib.decodeMonsterBits(p1, p2, p3);
mon.birthTime = mon2.birthTime;
mon.generation = mon2.generation;
mon.genes = mon2.genes;
mon.battleGenes = mon2.battleGenes;
mon.cooldownIndex = mon2.cooldownIndex;
mon.matronId = mon2.matronId;
mon.sireId = mon2.sireId;
mon.siringWithId = mon2.siringWithId;
mon.activeGrowCooldownIndex = mon2.activeGrowCooldownIndex;
mon.activeRestCooldownIndex = mon2.activeRestCooldownIndex;
mon.level = mon2.level;
mon.potionEffect = mon2.potionEffect;
mon.cooldownEndTimestamp = mon2.cooldownEndTimestamp;
mon.potionExpire = mon2.potionExpire;
mon.cooldownStartTimestamp = mon2.cooldownStartTimestamp;
mon.battleCounter = mon2.battleCounter;
}
}
/// @title Base contract for MonsterBit. Holds all common structs, events and base variables.
/// @dev See the MonsterCore contract documentation to understand how the various contract facets are arranged.
contract MonsterBase is MonsterAccessControl {
/*** EVENTS ***/
/// @dev The Birth event is fired whenever a new monster comes into existence. This obviously
/// includes any time a monster is created through the giveBirth method, but it is also called
/// when a new gen0 monster is created.
event Birth(address owner, uint256 monsterId, uint256 genes);
/// @dev Transfer event as defined in current draft of ERC721. Emitted every time a monster
/// ownership is assigned, including births.
event Transfer(address from, address to, uint256 tokenId);
/// @dev The address of the ClockAuction contract that handles sales of Monsters. This
/// same contract handles both peer-to-peer sales as well as the gen0 sales which are
/// initiated every 15 minutes.
SaleClockAuction public saleAuction;
SiringClockAuction public siringAuction;
MonsterBattles public battlesContract;
MonsterFood public monsterFood;
MonsterStorage public monsterStorage;
MonsterConstants public monsterConstants;
/// @dev The address of the sibling contract that is used to implement the sooper-sekret
/// genetic combination algorithm.
MonsterGeneticsInterface public geneScience;
function setMonsterStorageAddress(address _address) external onlyCEO {
MonsterStorage candidateContract = MonsterStorage(_address);
// NOTE: verify that a contract is what we expect
require(candidateContract.isMonsterStorage());
// Set the new contract address
monsterStorage = candidateContract;
}
function setMonsterConstantsAddress(address _address) external onlyCEO {
MonsterConstants candidateContract = MonsterConstants(_address);
// NOTE: verify that a contract is what we expect
require(candidateContract.isMonsterConstants());
// Set the new contract address
monsterConstants = candidateContract;
}
/// @dev Sets the reference to the battles contract.
/// @param _address - Address of battles contract.
function setBattlesAddress(address _address) external onlyCEO {
MonsterBattles candidateContract = MonsterBattles(_address);
// NOTE: verify that a contract is what we expect
require(candidateContract.isBattleContract());
// Set the new contract address
battlesContract = candidateContract;
}
/// @dev Assigns ownership of a specific Monster to an address.
function _transfer(address _from, address _to, uint256 _tokenId) internal {
// Since the number of monsters is capped to 2^32 we can't overflow this
uint count = monsterStorage.ownershipTokenCount(_to);
monsterStorage.setOwnershipTokenCount(_to, count + 1);
// transfer ownership
monsterStorage.setMonsterIndexToOwner(_tokenId, _to);
// When creating new monsters _from is 0x0, but we can't account that address.
if (_from != address(0)) {
count = monsterStorage.ownershipTokenCount(_from);
monsterStorage.setOwnershipTokenCount(_from, count - 1);
// clear any previously approved ownership exchange
monsterStorage.setMonsterIndexToApproved(_tokenId, address(0));
}
if(_from == address(saleAuction))
{
MonsterLib.Monster memory monster = readMonster(_tokenId);
if(monster.level == 0)
{
monsterStorage.setActionCooldown(_tokenId,
monster.cooldownIndex,
uint64(now + monsterConstants.growCooldowns(monster.activeGrowCooldownIndex)),
now,
monster.activeGrowCooldownIndex,
monster.activeRestCooldownIndex);
}
}
// Emit the transfer event.
emit Transfer(_from, _to, _tokenId);
}
/// @dev An internal method that creates a new monster and stores it. This
/// method doesn't do any checking and should only be called when the
/// input data is known to be valid. Will generate both a Birth event
/// and a Transfer event.
/// @param _generation The generation number of this monster, must be computed by caller.
/// @param _genes The monster's genetic code.
/// @param _owner The inital owner of this monster, must be non-zero (except for the unMonster, ID 0)
function _createMonster(
uint256 _matronId,
uint256 _sireId,
uint256 _generation,
uint256 _genes,
uint256 _battleGenes,
uint256 _level,
address _owner
)
internal
returns (uint)
{
require(_matronId == uint256(uint32(_matronId)));
require(_sireId == uint256(uint32(_sireId)));
require(_generation == uint256(uint16(_generation)));
MonsterLib.Monster memory _monster = MonsterLib.Monster({
genes: _genes,
birthTime: uint64(now),
cooldownEndTimestamp: 0,
matronId: uint32(_matronId),
sireId: uint32(_sireId),
siringWithId: uint32(0),
cooldownIndex: uint16(0),
generation: uint16(_generation),
battleGenes: uint64(_battleGenes),
level: uint8(_level),
activeGrowCooldownIndex: uint8(0),
activeRestCooldownIndex: uint8(0),
potionEffect: uint8(0),
potionExpire: uint64(0),
cooldownStartTimestamp: 0,
battleCounter: uint8(0)
});
setMonsterGrow(_monster);
(uint p1, uint p2, uint p3) = MonsterLib.encodeMonsterBits(_monster);
uint monsterId = monsterStorage.createMonster(p1, p2, p3);
// emit the birth event
emit Birth(
_owner,
monsterId,
_genes
);
// This will assign ownership, and also emit the Transfer event as
// per ERC721 draft
_transfer(0, _owner, monsterId);
return monsterId;
}
function setMonsterGrow(MonsterLib.Monster monster) internal view
{
//New monster starts with the same cooldown as parent gen/2
uint16 cooldownIndex = uint16(monster.generation / 2);
if (cooldownIndex > 13) {
cooldownIndex = 13;
}
monster.cooldownIndex = uint16(cooldownIndex);
if(monster.level == 0)
{
uint gen = monster.generation;
if(gen > monsterConstants.genToGrowCdIndexLength())
{
gen = monsterConstants.genToGrowCdIndexLength();
}
monster.activeGrowCooldownIndex = monsterConstants.genToGrowCdIndex(gen);
monster.cooldownEndTimestamp = uint64(now + monsterConstants.growCooldowns(monster.activeGrowCooldownIndex));
monster.cooldownStartTimestamp = uint64(now);
}
}
function readMonster(uint monsterId) internal view returns(MonsterLib.Monster)
{
(uint p1, uint p2, uint p3) = monsterStorage.getMonsterBits(monsterId);
MonsterLib.Monster memory mon = MonsterLib.decodeMonsterBits(p1, p2, p3);
return mon;
}
}
/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens
/// @author Dieter Shirley <[email protected]> (https://github.com/dete)
contract ERC721 {
// Required methods
function totalSupply() public view returns (uint256 total);
function balanceOf(address _owner) public view returns (uint256 balance);
function ownerOf(uint256 _tokenId) external view returns (address owner);
function approve(address _to, uint256 _tokenId) external;
function transfer(address _to, uint256 _tokenId) external;
function transferFrom(address _from, address _to, uint256 _tokenId) external;
// Events
event Transfer(address from, address to, uint256 tokenId);
event Approval(address owner, address approved, uint256 tokenId);
}
/// @title The facet of the MonsterBit core contract that manages ownership, ERC-721 (draft) compliant.
/// @dev Ref: https://github.com/ethereum/EIPs/issues/721
/// See the MonsterCore contract documentation to understand how the various contract facets are arranged.
contract MonsterOwnership is MonsterBase, ERC721 {
/// @notice Name and symbol of the non fungible token, as defined in ERC721.
string public constant name = "MonsterBit";
string public constant symbol = "MB";
/// @dev Checks if a given address is the current owner of a particular Monster.
/// @param _claimant the address we are validating against.
/// @param _tokenId monster id, only valid when > 0
function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) {
return monsterStorage.monsterIndexToOwner(_tokenId) == _claimant;
}
/// @dev Checks if a given address currently has transferApproval for a particular Monster.
/// @param _claimant the address we are confirming monster is approved for.
/// @param _tokenId monster id, only valid when > 0
function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) {
return monsterStorage.monsterIndexToApproved(_tokenId) == _claimant;
}
/// @dev Marks an address as being approved for transferFrom(), overwriting any previous
/// approval. Setting _approved to address(0) clears all transfer approval.
/// NOTE: _approve() does NOT send the Approval event. This is intentional because
/// _approve() and transferFrom() are used together for putting Monsters on auction, and
/// there is no value in spamming the log with Approval events in that case.
function _approve(uint256 _tokenId, address _approved) internal {
monsterStorage.setMonsterIndexToApproved(_tokenId, _approved);
}
/// @notice Returns the number of Monsters owned by a specific address.
/// @param _owner The owner address to check.
/// @dev Required for ERC-721 compliance
function balanceOf(address _owner) public view returns (uint256 count) {
return monsterStorage.ownershipTokenCount(_owner);
}
/// @notice Transfers a Monster to another address. If transferring to a smart
/// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or
/// MonsterBit specifically) or your Monster may be lost forever. Seriously.
/// @param _to The address of the recipient, can be a user or contract.
/// @param _tokenId The ID of the Monster to transfer.
/// @dev Required for ERC-721 compliance.
function transfer(
address _to,
uint256 _tokenId
)
external
whenNotPaused
{
// Safety check to prevent against an unexpected 0x0 default.
require(_to != address(0));
// Disallow transfers to this contract to prevent accidental misuse.
// The contract should never own any monsters (except very briefly
// after a gen0 monster is created and before it goes on auction).
require(_to != address(this));
// Disallow transfers to the auction contracts to prevent accidental
// misuse. Auction contracts should only take ownership of monsters
// through the allow + transferFrom flow.
require(_to != address(saleAuction));
// You can only send your own monster.
require(_owns(msg.sender, _tokenId));
// Reassign ownership, clear pending approvals, emit Transfer event.
_transfer(msg.sender, _to, _tokenId);
}
/// @notice Grant another address the right to transfer a specific Monster via
/// transferFrom(). This is the preferred flow for transfering NFTs to contracts.
/// @param _to The address to be granted transfer approval. Pass address(0) to
/// clear all approvals.
/// @param _tokenId The ID of the Monster that can be transferred if this call succeeds.
/// @dev Required for ERC-721 compliance.
function approve(
address _to,
uint256 _tokenId
)
external
whenNotPaused
{
// Only an owner can grant transfer approval.
require(_owns(msg.sender, _tokenId));
// Register the approval (replacing any previous approval).
_approve(_tokenId, _to);
// Emit approval event.
emit Approval(msg.sender, _to, _tokenId);
}
/// @notice Transfer a Monster owned by another address, for which the calling address
/// has previously been granted transfer approval by the owner.
/// @param _from The address that owns the Monster to be transfered.
/// @param _to The address that should take ownership of the Monster. Can be any address,
/// including the caller.
/// @param _tokenId The ID of the Monster to be transferred.
/// @dev Required for ERC-721 compliance.
function transferFrom(
address _from,
address _to,
uint256 _tokenId
)
external
whenNotPaused
{
// Safety check to prevent against an unexpected 0x0 default.
require(_to != address(0));
// Disallow transfers to this contract to prevent accidental misuse.
// The contract should never own any monsters (except very briefly
// after a gen0 monster is created and before it goes on auction).
require(_to != address(this));
// Check for approval and valid ownership
require(_approvedFor(msg.sender, _tokenId));
require(_owns(_from, _tokenId));
// Reassign ownership (also clears pending approvals and emits Transfer event).
_transfer(_from, _to, _tokenId);
}
/// @notice Returns the total number of Monsters currently in existence.
/// @dev Required for ERC-721 compliance.
function totalSupply() public view returns (uint) {
return monsterStorage.getMonstersCount() - 1;
}
/// @notice Returns the address currently assigned ownership of a given Monster.
/// @dev Required for ERC-721 compliance.
function ownerOf(uint256 _tokenId)
external
view
returns (address owner)
{
owner = monsterStorage.monsterIndexToOwner(_tokenId);
require(owner != address(0));
}
/// @notice Returns a list of all Monster IDs assigned to an address.
/// @param _owner The owner whose Monsters we are interested in.
/// @dev This method MUST NEVER be called by smart contract code. First, it's fairly
/// expensive (it walks the entire Monster array looking for monsters belonging to owner),
/// but it also returns a dynamic array, which is only supported for web3 calls, and
/// not contract-to-contract calls.
function tokensOfOwner(address _owner) external view returns(uint256[] ownerTokens) {
uint256 tokenCount = balanceOf(_owner);
if (tokenCount == 0) {
// Return an empty array
return new uint256[](0);
} else {
uint256[] memory result = new uint256[](tokenCount);
uint256 totalMonsters = totalSupply();
uint256 resultIndex = 0;
// We count on the fact that all monsters have IDs starting at 1 and increasing
// sequentially up to the totalMonsters count.
uint256 monsterId;
for (monsterId = 1; monsterId <= totalMonsters; monsterId++) {
if (monsterStorage.monsterIndexToOwner(monsterId) == _owner) {
result[resultIndex] = monsterId;
resultIndex++;
}
}
return result;
}
}
}
/// @title A facet of MosterBitCore that manages Monster siring, gestation, and birth.
contract MonsterBreeding is MonsterOwnership {
/// @dev The Pregnant event is fired when two monster successfully breed and the pregnancy
/// timer begins for the matron.
event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndTimestamp);
/// @notice The minimum payment required to use breedWithAuto(). This fee goes towards
/// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by
/// the COO role as the gas price changes.
uint256 public autoBirthFee = 2 finney;
uint256 public birthCommission = 5 finney;
/// @dev Update the address of the genetic contract, can only be called by the CEO.
/// @param _address An address of a GeneScience contract instance to be used from this point forward.
function setGeneScienceAddress(address _address) external onlyCEO {
MonsterGeneticsInterface candidateContract = MonsterGeneticsInterface(_address);
// NOTE: verify that a contract is what we expect
require(candidateContract.isMonsterGenetics());
// Set the new contract address
geneScience = candidateContract;
}
function setSiringAuctionAddress(address _address) external onlyCEO {
SiringClockAuction candidateContract = SiringClockAuction(_address);
// NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117
require(candidateContract.isSiringClockAuction());
// Set the new contract address
siringAuction = candidateContract;
}
/// @dev Checks that a given monster is able to breed. Requires that the
/// current cooldown is finished (for sires) and also checks that there is
/// no pending pregnancy.
function _isReadyToBreed(MonsterLib.Monster _monster) internal view returns (bool) {
// In addition to checking the cooldownEndTimestamp, we also need to check to see if
// the cat has a pending birth; there can be some period of time between the end
// of the pregnacy timer and the birth event.
return (_monster.siringWithId == 0) && (_monster.cooldownEndTimestamp <= uint64(now) && (_monster.level >= 1));
}
/// @dev Check if a sire has authorized breeding with this matron. True if both sire
/// and matron have the same owner, or if the sire has given siring permission to
/// the matron's owner (via approveSiring()).
function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) {
address matronOwner = monsterStorage.monsterIndexToOwner(_matronId);
address sireOwner = monsterStorage.monsterIndexToOwner(_sireId);
// Siring is okay if they have same owner, or if the matron's owner was given
// permission to breed with this sire.
return (matronOwner == sireOwner || monsterStorage.sireAllowedToAddress(_sireId) == matronOwner);
}
/// @dev Set the cooldownEndTime for the given monster, based on its current cooldownIndex.
/// Also increments the cooldownIndex (unless it has hit the cap).
/// @param _monster A reference to the monster in storage which needs its timer started.
function _triggerCooldown(uint monsterId, MonsterLib.Monster _monster, uint increaseIndex) internal {
uint activeRestCooldownIndex = _monster.cooldownIndex;
uint cooldownEndTimestamp = uint64(monsterConstants.actionCooldowns(activeRestCooldownIndex) + now);
uint newCooldownIndex = _monster.cooldownIndex;
// Increment the breeding count, clamping it at 13, which is the length of the
// cooldowns array. We could check the array size dynamically, but hard-coding
// this as a constant saves gas. Yay, Solidity!
if(increaseIndex > 0)
{
if (newCooldownIndex + 1 < monsterConstants.actionCooldownsLength()) {
newCooldownIndex += 1;
}
}
monsterStorage.setActionCooldown(monsterId, newCooldownIndex, cooldownEndTimestamp, now, 0, activeRestCooldownIndex);
}
/// @notice Grants approval to another user to sire with one of your monsters.
/// @param _addr The address that will be able to sire with your monster. Set to
/// address(0) to clear all siring approvals for this monster.
/// @param _sireId A monster that you own that _addr will now be able to sire with.
function approveSiring(address _addr, uint256 _sireId)
external
whenNotPaused
{
require(_owns(msg.sender, _sireId));
monsterStorage.setSireAllowedToAddress(_sireId, _addr);
}
/// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only
/// be called by the COO address. (This fee is used to offset the gas cost incurred
/// by the autobirth daemon).
function setAutoBirthFee(uint256 val) external onlyCOO {
autoBirthFee = val;
}
function setBirthCommission(uint val) external onlyCOO{
birthCommission = val;
}
/// @dev Checks to see if a given monster is pregnant and (if so) if the gestation
/// period has passed.
function _isReadyToGiveBirth(MonsterLib.Monster _matron) private view returns (bool) {
return (_matron.siringWithId != 0) && (_matron.cooldownEndTimestamp <= now);
}
/// @notice Checks that a given monster is able to breed (i.e. it is not pregnant or
/// in the middle of a siring cooldown).
/// @param _monsterId reference the id of the monster, any user can inquire about it
function isReadyToBreed(uint256 _monsterId)
public
view
returns (bool)
{
require(_monsterId > 0);
MonsterLib.Monster memory monster = readMonster(_monsterId);
return _isReadyToBreed(monster);
}
/// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT
/// check ownership permissions (that is up to the caller).
/// @param _matron A reference to the monster struct of the potential matron.
/// @param _matronId The matron's ID.
/// @param _sire A reference to the monster struct of the potential sire.
/// @param _sireId The sire's ID
function _isValidMatingPair(
MonsterLib.Monster _matron,
uint256 _matronId,
MonsterLib.Monster _sire,
uint256 _sireId
)
internal
pure
returns(bool)
{
// A monster can't breed with itself!
if (_matronId == _sireId) {
return false;
}
// monsters can't breed with their parents.
if (_matron.matronId == _sireId || _matron.sireId == _sireId) {
return false;
}
if (_sire.matronId == _matronId || _sire.sireId == _matronId) {
return false;
}
// We can short circuit the sibling check (below) if either cat is
// gen zero (has a matron ID of zero).
if (_sire.matronId == 0 || _matron.matronId == 0) {
return true;
}
// monster can't breed with full or half siblings.
if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) {
return false;
}
if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) {
return false;
}
// Everything seems cool! Let's get DTF.
return true;
}
/// @dev Checks whether a monster is currently pregnant.
/// @param _monsterId reference the id of the monster, any user can inquire about it
function isPregnant(uint256 _monsterId)
public
view
returns (bool)
{
require(_monsterId > 0);
// A monster is pregnant if and only if this field is set
MonsterLib.Monster memory monster = readMonster(_monsterId);
return monster.siringWithId != 0;
}
/// @dev Internal check to see if a given sire and matron are a valid mating pair for
/// breeding via auction (i.e. skips ownership and siring approval checks).
function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId)
internal
view
returns (bool)
{
MonsterLib.Monster memory matron = readMonster(_matronId);
MonsterLib.Monster memory sire = readMonster(_sireId);
return _isValidMatingPair(matron, _matronId, sire, _sireId);
}
/// @notice Checks to see if two monsters can breed together, including checks for
/// ownership and siring approvals. Does NOT check that both cats are ready for
/// breeding (i.e. breedWith could still fail until the cooldowns are finished).
/// @param _matronId The ID of the proposed matron.
/// @param _sireId The ID of the proposed sire.
function canBreedWith(uint256 _matronId, uint256 _sireId)
external
view
returns(bool)
{
require(_matronId > 0);
require(_sireId > 0);
MonsterLib.Monster memory matron = readMonster(_matronId);
MonsterLib.Monster memory sire = readMonster(_sireId);
return _isValidMatingPair(matron, _matronId, sire, _sireId) &&
_isSiringPermitted(_sireId, _matronId);
}
/// @dev Internal utility function to initiate breeding, assumes that all breeding
/// requirements have been checked.
function _breedWith(uint256 _matronId, uint256 _sireId) internal {
// Grab a reference to the Kitties from storage.
MonsterLib.Monster memory sire = readMonster(_sireId);
MonsterLib.Monster memory matron = readMonster(_matronId);
// Mark the matron as pregnant, keeping track of who the sire is.
monsterStor...
// [truncated — 72032 bytes total]
Read Contract
GEN0_AUCTION_DURATION 0x19c2f201 → uint256
GEN0_CREATION_LIMIT 0x680eba27 → uint256
GEN0_ENDING_PRICE 0x3304cbff → uint256
GEN0_STARTING_PRICE 0x0e583df0 → uint256
PROMO_CREATION_LIMIT 0xdefb9584 → uint256
autoBirthFee 0xb0c35c05 → uint256
balanceOf 0x70a08231 → uint256
battlesContract 0xe4c73abe → address
birthCommission 0x1caa79f9 → uint256
canBreedWith 0x46d22c70 → bool
ceoAddress 0x0a0f8168 → address
cfoAddress 0x0519ce79 → address
cooAddress 0xb047fb50 → address
gen0CreatedCount 0xf1ca9410 → uint256
geneScience 0xf2b47d52 → address
isPregnant 0x1940a936 → bool
isReadyToBreed 0xd3e6f49f → bool
monsterConstants 0xe06f96e2 → address
monsterFood 0xa6531d34 → address
monsterStorage 0xd75b855a → address
name 0x06fdde03 → string
newContractAddress 0x6af04a57 → address
ownerOf 0x6352211e → address
paused 0x5c975abb → bool
promoCreatedCount 0x05e45546 → uint256
saleAuction 0xe6cbe351 → address
siringAuction 0x21717ebf → address
symbol 0x95d89b41 → string
tokensOfOwner 0x8462151c → uint256[]
totalSupply 0x18160ddd → uint256
Write Contract 32 functions
These functions modify contract state and require a wallet transaction to execute.
approve 0x095ea7b3
address _to
uint256 _tokenId
approveSiring 0x4dfff04f
address _addr
uint256 _sireId
bidOnSiringAuction 0xed60ade6
uint256 _sireId
uint256 _matronId
breedWithAuto 0xf7d8c883
uint256 _matronId
uint256 _sireId
createGen0AuctionCustom 0xe065efbb
uint256 _genes
uint256 _battleGenes
uint256 _level
uint256 _startingPrice
uint256 _endingPrice
uint256 _duration
createPromoMonster 0xc0e9b0c2
uint256 _genes
uint256 _battleGenes
uint256 _level
address _owner
createSaleAuction 0x3d7d3f5a
uint256 _monsterId
uint256 _startingPrice
uint256 _endingPrice
uint256 _duration
createSiringAuction 0x4ad8c938
uint256 _monsterId
uint256 _startingPrice
uint256 _endingPrice
uint256 _duration
feedMonster 0x9c1cb8bf
uint256 _monsterId
uint256 _foodCode
finishBattle 0xe23d5314
uint256 _param1
uint256 _param2
uint256 _param3
returns: uint256
giveBirth 0x88c2a0bf
uint256 _matronId
returns: uint256
pause 0x8456cb59
No parameters
prepareForBattle 0x48648a6f
uint256 _param1
uint256 _param2
uint256 _param3
returns: uint256
setAutoBirthFee 0x4b85fd55
uint256 val
setBattlesAddress 0x96baf2bd
address _address
setBirthCommission 0x562340cf
uint256 val
setCEO 0x27d7874c
address _newCEO
setCFO 0x4e0a3379
address _newCFO
setCOO 0x2ba73c15
address _newCOO
setGeneScienceAddress 0x24e7a38a
address _address
setMonsterConstantsAddress 0x46a89ada
address _address
setMonsterFoodAddress 0x82877bf0
address _address
setMonsterStorageAddress 0x7a87bb91
address _address
setNewAddress 0x71587988
address _v2Address
setSaleAuctionAddress 0x6fbde40d
address _address
setSiringAuctionAddress 0x14001f4c
address _address
transfer 0xa9059cbb
address _to
uint256 _tokenId
transferFrom 0x23b872dd
address _from
address _to
uint256 _tokenId
unpause 0x3f4ba83a
No parameters
withdrawBalance 0x5fd8c710
No parameters
withdrawDependentBalances 0x53d89094
No parameters
withdrawFromBattle 0x9c56e5d7
uint256 _param1
uint256 _param2
uint256 _param3
returns: uint256
Recent Transactions
No transactions found for this address