Address Contract Verified
Address
0x6F2aF87135FEfbd60bc3b4478f0770640c125B6D
Balance
0 ETH
Nonce
1
Code Size
7861 bytes
Creator
0x32caD849...E13c at tx 0xabc36955...dd9846
Indexed Transactions
0
Contract Bytecode
7861 bytes
0x608060408181526004918236101561001657600080fd5b600092833560e01c9182630dd3930d1461125757508163361652c91461118a57816337d2aae91461105c57816355b43fe114610de657816360e72adb14610bd257816368c3362714610b7c578163710dc95714610b5d5781637785c0b614610b015781638694af78146109f55781638a3a8b291461093f5781639e5d82b914610904578163bb6c191a14610846578163bb87d2aa14610485578163c0f1d8c6146103a1578163d5002f2e1461037f578163dcb6f63814610308578163f8c7038714610231578163fafc08c414610181575063fe7f3b51146100f657600080fd5b3461017d578160031936011261017d579060a0825161011481611587565b36903781518092600a92935b6001906005828701101561015557908260029286546001600160801b038116825260801c602082015201940194019392610120565b61017b9291506001600160801b0360a0955416905261017383611587565b518092611664565bf35b5080fd5b90503461022d576020908160031936011261022957356001600160a01b038116908190036102295783526001808252828420835181548082529186528386208185019693949192879190855b81811061021657505050826101e39103836115bd565b8451948186019282875251809352850195925b8281106102035785870386f35b83518752958101959281019284016101f6565b82548452928401929187019187016101cd565b8380fd5b8280fd5b828434610305578060031936011261030557600f5482516370a0823160e01b8152308582015290602090829060249082906001600160a01b03165afa9081156102fb5782916102ca575b506001600160801b03600e541691670de0b6b3a7640000928381029381850414901517156102b7576020846102b08585611983565b9051908152f35b634e487b7160e01b815260118552602490fd5b90506020813d82116102f3575b816102e4602093836115bd565b8101031261017d57518461027b565b3d91506102d7565b83513d84823e3d90fd5b80fd5b905082346103055780600319360112610305579060c083516103298161156c565b36903782519091815b6001906006828401101561036757908560029286546001600160801b038116825260801c602082015201940191019092610332565b60c08461017b886103778361156c565b518092611633565b50503461017d578160031936011261017d57602090600d5460801c9051908152f35b50503461017d57602036600319011261017d576102b0602092826001600160801b0391826103cd6115de565b1681526002865220908351916103e28361153b565b54906001600160401b038083168452868401938284881c16855261042c64ffffffffff8560c01c16808984015260ff606084019660e81c16865261042461174a565b904211611722565b61046f828251161515885190610441826115a2565b601b82527f5374616b696e673a205374616b696e67206e6f742065786973747300000000008b830152611722565b511692511660ff600d5460801c92511692611d0a565b83833461017d57606036600319011261017d576104a061160d565b6104a8611623565b9160018060a01b0391826010541682516331a9108f60e11b815260443588820152602081602481855afa90811561083c5787916107fc575b50602491610528602092878751916104f7836115a2565b601e83527f5374616b696e673a205a6f6d626965206f776e6572207265717569726564000086840152163314611722565b8451635284cdd760e11b81526044358a82015292839182905afa9081156107f25786916107af575b509061055e6105c792611bfd565b9361057b61056a611ac7565b6001600160401b0384161515611722565b610592610586611b00565b600660ff891610611722565b61059b86611b56565b93906105c26001600160801b0380966001600160401b03871693549060031b1c1688611bc4565b611bc4565b600d5484811685811461079c57908986600181940116809a816001600160801b031980951617600d553383526001602052610604828b8520611c66565b5064ffffffffff6106388661063161062c8261061f87611b71565b90549060031b1c16611b8c565b611ba7565b16426117ac565b166001600160401b038b80519561064e8761153b565b828c1687526020870195898b16875282880194855260ff60608901961686528152600260205220945116600160401b600160c01b03855494518d1b169164ffffffffff60c01b905160c01b169260ff60e81b905160e81b169361ffff60f01b16171717179055600e5481836106ce6001600160401b038916828516611be2565b16911617600e556106e5600d54938460801c611be2565b60801b16911617600d55670de0b6b3a7640000916001600160401b038381831602938183168504149116151715610789577f42429601bd1b722443ccb2a6ae7a2f2c054a4793932abbf351508fa261b9a32293929161077591600f54168451916323b872dd60e01b602084015233602484015230604484015260648301526064825261077082611587565b6117d2565b81519360443585521660208401523392a380f35b634e487b7160e01b875260118852602487fd5b634e487b7160e01b8a5260118b5260248afd5b90506020813d6020116107ea575b816107ca602093836115bd565b810103126107e6575161ffff811681036107e65761055e610550565b8580fd5b3d91506107bd565b83513d88823e3d90fd5b90506020813d602011610834575b81610817602093836115bd565b81010312610830575184811681036108305760246104e0565b8680fd5b3d915061080a565b84513d89823e3d90fd5b82843461030557816003193601126103055761086061160d565b9060646001600160401b03610873611623565b931691610889610881611ac7565b841515611722565b6108a0610894611b00565b600660ff871610611722565b6108a984611b56565b92906108c7856001600160801b0380968194549060031b1c16611bc4565b16029182169182036108f1576020856102b08686866108eb81600d5460801c611be2565b91611d0a565b634e487b7160e01b815260118652602490fd5b50503461017d57602036600319011261017d57602091816001600160801b03918261092d6115de565b1681526002855220548251921c168152f35b50503461017d57602036600319011261017d579060ff826080936109616115de565b9380606083516109708161153b565b828152826020820152828582015201526001600160801b038095168152600260205220908051916109a08361153b565b54916001600160401b0383169485825260208201908085851c1682528383019186606064ffffffffff95868960c01c168652019660e81c16865284519788525116602087015251169084015251166060820152f35b82843461030557606036600319011261030557610a1061160d565b610a18611623565b916044359060ff82169283830361017d576001600160401b03610a93911693610a4a610a42611ac7565b861515611722565b610a55610586611b00565b6005875191610a63836115a2565b602083527f5374616b696e673a205a6f6d626965206c6576656c20697320696e76616c6964602084015210611722565b6005821015610aee576020856102b08686610adf816105c28960808160011c600a0154610abf88611b56565b92906001600160801b03938491549060031b1c169360071b161c16611bc4565b6108eb81600d5460801c611be2565b634e487b7160e01b815260328652602490fd5b82843461030557806003193601126103055760c08251610b208161156c565b36903781516007916001826006828401101561036757908560029286546001600160801b038116825260801c602082015201940191019092610332565b50503461017d578160031936011261017d576020906003549051908152f35b83833461017d578160031936011261017d576001600160801b03600e541691670de0b6b3a764000092838102938185041490151715610bbf576020838351908152f35b634e487b7160e01b815260118452602490fd5b90503461022d576020908160031936011261022957610bef6115de565b923385526001835280852093610c5d610c236001600160801b03809316809760019160005201602052604060002054151590565b835190610c2f826115a2565b601e82527f5374616b696e673a205374616b696e6720696420697320696e76616c6964000087830152611722565b8486526002845281862092825193610c748561153b565b54936001600160401b039182861682528682018487871c168152610cb664ffffffffff8860c01c16808886015260ff606086019960e81c16895261042461174a565b8383511691670de0b6b3a764000092838102938185041490151715610dd3575090848392858296955116928282511693600d54948560801c809c5160ff1691610cfe93611d0a565b90610d08916117ac565b986001600160801b03199687925116610d20916117b9565b60801b16911617600d55511691600e549281841690610d3e916117b9565b16911617600e55338552600183528381862090610d5a916119be565b5083855260028352808520859055600f54815163a9059cbb60e01b81860152336024820152604480820185905281526001600160a01b0390911690610d9e8161153b565b610da7916117d2565b5190815233917facdcb9041bb85f01fdf7810fea123661a101242c5fe3cb55c577abdbfd8351c291a380f35b634e487b7160e01b8b526011905260248afd5b9190503461022d578060031936011261022d57610e0161160d565b610e09611623565b926001600160401b0380921691821590610e2b610e24611ac7565b8315611722565b60ff861690610e44610e3b611b00565b60068410611722565b610e4d87611b56565b91906001600160801b03928391549060031b1c166064028281169081036110495786610e7891611bc4565b92600d5491838316848114611036579189918580808f96600101169d8e8096816001600160801b0319809b1617600d553389526001602052882090610ebc91611c66565b50610ec690611b71565b90549060031b1c16610ed790611b8c565b610ee090611ba7565b610eeb9116426117ac565b64ffffffffff16908b805195610f008761153b565b8c87526020870195898b168752828801948552606088019586528152600260205220945116845493518c1b600160401b600160c01b03169164ffffffffff60c01b905160c01b169260ff60e81b905160e81b169361ffff60f01b16171717179055600e5481838881841690610f7491611be2565b16911617600e55600d54928360801c90610f8d91611be2565b60801b16911617600d55670de0b6b3a76400008084029384041417156110235750600f5482516323b872dd60e01b6020820152336024820152306044820152606480820193909352918252610fef91906001600160a01b031661077082611587565b7f42429601bd1b722443ccb2a6ae7a2f2c054a4793932abbf351508fa261b9a322815191848352606460208401523392a380f35b634e487b7160e01b855260119052602484fd5b634e487b7160e01b8c526011885260248cfd5b634e487b7160e01b8a526011865260248afd5b90503461022d57602080600319360112610229576001600160a01b038235818116949193908590036107e65785548251630f6266a760e01b81523092810192835233602084015290948516918490829081906040010381855afa908115611180577247756172643a207a65726f206164647265737360681b926110f8611143969593611129938b91611153575b506110f26116ad565b90611722565b87835191611105836115a2565b601183527047756172643a2073616d652076616c756560781b878401521415611722565b5191611134836115a2565b60138352820152831515611722565b6001600160a01b03191617815580f35b6111739150873d8911611179575b61116b81836115bd565b810190611695565b386110e9565b503d611161565b83513d89823e3d90fd5b90503461022d57602036600319011261022d5780359063ffffffff82168092036102295783548351630f6266a760e01b815230928101928352336020808501919091529092909183918290036040019082906001600160a01b03165afa90811561124a5792611227602093927fee2589b7e912878a6a500663abeeaa8eb0bc43c6ef8626f3a6706962e7784dc395879161123357506110f26116ad565b8160035551908152a180f35b6111739150853d81116111795761116b81836115bd565b50505051903d90823e3d90fd5b83828634610305576101609081600319360112610305573660231215610305576112808561156c565b60c4938536861161022d5784905b8682106115235750503660e3121561017d578051946112ac86611587565b856101649136831161151f57905b82821061150757505082548251630f6266a760e01b8152308782019081523360208281019190915293509091839183916001600160a01b0316908290819060400103915afa90811561124a579061131a9185916114ea57506110f26116ad565b825b600681106114c45750825b60058082101561135b57906113516001600160801b0382611356941b8a01511615156110f2611cd1565b611cc2565b611327565b50508686949581855b600381106114705750508591855b6002808210156113d457879088905b8781831061139957505050600a820155600101611372565b6113ca88946001600160801b03600194959a5116908a8a1b60031b6001600160801b03811b9283911b169119161790565b9301960190611381565b505093919096949592968697875b6001811061143257505050509061142461142e927fc167bb3935aa4427dca7338db343e033afb1111a921c79afe8eb3a5f4355b4cc9697600c55518094611633565b60c0830190611664565ba180f35b90919298826114656001926001600160801b038d51169085881b60031b6001600160801b03811b9283911b169119161790565b9a01939291016113e2565b86875b866002821061148b5750506007820155600101611364565b6114bb85936001600160801b036001949751169087891b60031b6001600160801b03811b9283911b169119161790565b92019301611473565b806113516001600160801b036114e59360051b8b01511615156110f2611cd1565b61131c565b6115019150833d85116111795761116b81836115bd565b896110e9565b60208091611514846115f9565b8152019101906112ba565b8480fd5b60208091611530846115f9565b81520191019061128e565b608081019081106001600160401b0382111761155657604052565b634e487b7160e01b600052604160045260246000fd5b60c081019081106001600160401b0382111761155657604052565b60a081019081106001600160401b0382111761155657604052565b604081019081106001600160401b0382111761155657604052565b90601f801991011681019081106001600160401b0382111761155657604052565b600435906001600160801b03821682036115f457565b600080fd5b35906001600160801b03821682036115f457565b600435906001600160401b03821682036115f457565b6024359060ff821682036115f457565b6000915b6006831061164457505050565b6001906001600160801b0383511681526020809101920192019190611637565b6000915b6005831061167557505050565b6001906001600160801b0383511681526020809101920192019190611668565b908160209103126115f4575180151581036115f45790565b604051906116ba826115a2565b601082526f47756172643a204e6f2072696768747360801b6020830152565b6020808252825181830181905290939260005b82811061170e57505060409293506000838284010152601f8019910116010190565b8181018601518482016040015285016116ec565b1561172a5750565b60405162461bcd60e51b815290819061174690600483016116d9565b0390fd5b60405190611757826115a2565b601b82527f5374616b696e67205374616b696e67206973206e6f74206f76657200000000006020830152565b8181029291811591840414171561179657565b634e487b7160e01b600052601160045260246000fd5b9190820180921161179657565b6001600160801b03918216908216039190821161179657565b6040516001600160a01b039091169291906117ec816115a2565b6020918282527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564838301526000808285829451910182895af13d15611902573d956001600160401b0387116118ee576118669495966040519061185888601f19601f84011601836115bd565b81528093873d92013e61190e565b8051908282159283156118d6575b5050501561187f5750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b6118e69350820181019101611695565b388281611874565b634e487b7160e01b83526041600452602483fd5b61186693949591506060915b919290156119705750815115611922575090565b3b1561192b5790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b82519091501561172a5750805190602001fd5b9190820391821161179657565b80548210156119a85760005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b90600182019060009281845282602052604084205490811515600014611ac05760001991808301818111611aac57825490848201918211611a9857808203611a4a575b50505080548015611a3657820191611a198383611990565b909182549160031b1b191690555582526020526040812055600190565b634e487b7160e01b86526031600452602486fd5b611a83611a5a611a6a9386611990565b90549060031b1c92839286611990565b819391549060031b600019811b9283911b169119161790565b90558652846020526040862055388080611a01565b634e487b7160e01b88526011600452602488fd5b634e487b7160e01b87526011600452602487fd5b5050505090565b60405190611ad4826115a2565b601c82527f5374616b696e673a20526571756972656420616d6f756e74203e2030000000006020830152565b60405190606082018281106001600160401b03821117611556576040526024825263185b1a5960e21b6040837f5374616b696e673a205374616b696e6720696e74657276616c20697320696e7660208201520152565b9060068210156119a85760108260011c6007019260041b1690565b9060068210156119a85760108260011c6004019260041b1690565b90601e6001600160801b038093160291821691820361179657565b90620151806001600160801b038093160291821691820361179657565b9190916001600160801b038080941691160291821691820361179657565b9190916001600160801b038080941691160191821161179657565b61ffff1661047e8111611c1a57506001600160801b03600a541690565b6104f68111611c2d5750600a5460801c90565b61056e8111611c4657506001600160801b03600b541690565b6105d210611c5757600b5460801c90565b6001600160801b03600c541690565b6000828152600182016020526040902054611cbb57805490680100000000000000008210156115565782611ca4611a6a846001809601855584611990565b905580549260005201602052604060002055600190565b5050600090565b60001981146117965760010190565b60405190611cde826115a2565b601982527f5374616b696e673a20496e70757420697320696e76616c6964000000000000006020830152565b9260018060a01b03600f5416604051936370a0823160e01b855260208560248160049530878301525afa948515611e7357600095611e40575b506001600160801b039384600e5416670de0b6b3a76400009687820291808304891490151715611e2b579186611d7d611d85938295611983565b911690611783565b9116908115611e165790611da191049584600354911690611783565b848102948186041490151715611e01576006821015611dec5791816080611dda946201d4c0969460011c01549160071b161c1690611783565b0480821015611de7575090565b905090565b603290634e487b7160e01b6000525260246000fd5b601190634e487b7160e01b6000525260246000fd5b601283634e487b7160e01b6000525260246000fd5b601185634e487b7160e01b6000525260246000fd5b90946020823d8211611e6b575b81611e5a602093836115bd565b810103126103055750519338611d43565b3d9150611e4d565b6040513d6000823e3d90fdfea2646970667358221220fd48593135757eab36a6bc5597a6dd0846258c1d9b2e404f595265d728b72c2564736f6c63430008110033
Verified Source Code Full Match
Compiler: v0.8.17+commit.8df45f5f
EVM: london
Optimization: Yes (200 runs)
Guard.sol 33 lines
// SPDX-License-Identifier: PROPRIERTARY // Author: Ilya A. Shlyakhovoy // Email: [email protected] pragma solidity 0.8.17; import "./interfaces/IRights.sol"; abstract contract Guard { string constant NO_RIGHTS = "Guard: No rights"; /// @notice only if person with rights calls the contract modifier haveRights() { require(_rights().haveRights(address(this), msg.sender), NO_RIGHTS); _; } /// @notice only if someone with rights calls the contract modifier haveRightsPerson(address who_) { require(_rights().haveRights(address(this), who_), NO_RIGHTS); _; } /// @notice only if who with rights calls the target function modifier haveRightsExt(address target_, address who_) { require(_rights().haveRights(target_, who_), NO_RIGHTS); _; } function _rights() internal view virtual returns (IRights); function setRights(address rights_) external virtual; }
Structures.sol 97 lines
// SPDX-License-Identifier: PROPRIERTARY // Author: Ilya A. Shlyakhovoy // Email: [email protected] pragma solidity 0.8.17; /** * @dev Collection of structures */ library Structures { struct ActorData { uint256 adultTime; uint256 bornTime; string kidTokenUriHash; string adultTokenUriHash; uint16[10] props; uint8 childs; uint8 childsPossible; bool sex; bool born; bool immaculate; uint16 rank; address initialOwner; } struct Item { string itemKey; uint256 location; uint8 slots; string uri; } struct LootBox { uint256 price; uint16 total; uint16 available; bool paused; bool deleted; string uri; LootBoxItem[] items; } struct LootBoxItem { uint256 class; uint256 model; uint8 slots; uint16 promilles; } struct Estate { address lender; uint256 location; uint8 estateType; uint256 parent; uint256 coordinates; } struct Villa { uint256 location; uint256 fraction; } struct ManageAction { address target; address author; uint256 expiration; bytes4 signature; bytes data; bool executed; } struct InvestorData { address investor; uint256 promille; } struct Benefit { uint256 price; uint256 from; uint256 until; uint16 id; uint16 amount; uint8 level; uint8 issued; } struct BreedingParams { uint256 motherId; uint256 fatherId; uint256 breedingId; uint256 sessionId; uint256 breedingFee; uint256 deadline; address asset; bool isKidForMother; } }
Staking.sol 351 lines
// SPDX-License-Identifier: PROPRIERTARY // Author: Dmitry Kharlanchuk // Email: [email protected] pragma solidity 0.8.17; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "../utils/GuardExtension.sol"; import "../persons/interfaces/IActors.sol"; import "./interfaces/IStaking.sol"; contract Staking is IStaking, GuardExtension { using EnumerableSet for EnumerableSet.UintSet; using SafeERC20 for IERC20; mapping(address => EnumerableSet.UintSet) _stakesByAddress; mapping(uint128 => Stake) _stakes; uint256 private _maxAPR; // two decimals 100% == 10000 uint128[6] private _intervalsMonth; uint128[6] private _intervalCoefficient; uint128[5] private _boosterCoefficient; uint128 private _counter; // Decimal places are not taken // Total supply 250,000,000 UDS uint128 private _totalShares; uint128 private totalStakes; IERC20 private _udsToken; IActors private _zombies; string private constant ZERO_AMOUNT = "Staking: Required amount > 0"; string private constant NOT_ZOMBIE_OWNER = "Staking: Zombie owner required"; string private constant NOT_EXISTS = "Staking: Staking not exists"; string private constant NOT_OVER = "Staking Staking is not over"; string private constant ALREADY_REWARDED = "Staking: Already rewarded"; string private constant INVALID_ZOMBIE_LEVEL = "Staking: Zombie level is invalid"; string private constant INVALID_INTERVAL = "Staking: Staking interval is invalid"; string private constant INVALID_STAKING_ID = "Staking: Staking id is invalid"; string private constant INVALID_INPUT = "Staking: Input is invalid"; constructor( address rights_, address udsToken_, address zombies_, uint16 maxAPR_, uint128[6] memory intervalsMonth_, uint128[6] memory intervalCoefficients_, uint128[5] memory boosterCoefficients_ ) GuardExtension(rights_) { _udsToken = IERC20(udsToken_); _zombies = IActors(zombies_); _setCoefficients(intervalCoefficients_, boosterCoefficients_); _setMaxApr(maxAPR_); _intervalsMonth = intervalsMonth_; _totalShares = 1; // set minimal shares to avoid devide by zero } /** * @dev Sets coefficients for staking time and the presence of zombie. * The coefficient requires 2 decimal places (1.0 == 100) * @param intervalCoefficients_ Coefficients for staking time correspond to _intervalsMonth. * @param boosterCoefficients_ Coefficients for owning zombies correspond to the level of zombies. */ function setCoefficients( uint128[6] memory intervalCoefficients_, uint128[5] memory boosterCoefficients_ ) external haveRights { _setCoefficients(intervalCoefficients_, boosterCoefficients_); } /** * @dev Sets the upper limit of APR. * @param maxAPR_ Maximum APR percentage to two decimal places (100% == 10000). */ function setMaxApr(uint32 maxAPR_) external haveRights { _setMaxApr(maxAPR_); } /** * @dev Stake user tokens for a specified period of time. * @param stakeAmount_ Number of tokens for staking. Specified without decimal places. * @param interval_ Time interval index 0-5 (see getMonthIntervals()). */ function stake(uint64 stakeAmount_, uint8 interval_) public { _stake(stakeAmount_, interval_, 100, 0); } /** * @dev Stake user tokens for a specified period of time with discount for zombiew owners. * @param stakeAmount_ Number of tokens for staking. Specified without decimal places. * @param interval_ Time interval index 0-5 (see getMonthIntervals()). * @param zombieId_ Zombie ID. */ function stakeByZombieOwner( uint64 stakeAmount_, uint8 interval_, uint256 zombieId_ ) public { require(msg.sender == _zombies.ownerOf(zombieId_), NOT_ZOMBIE_OWNER); uint16 rank = _zombies.getRank(zombieId_); _stake(stakeAmount_, interval_, _getBoostByRank(rank), zombieId_); } /** * @dev Returns staked tokens along with the reward. * @param stakeId_ Staking ID. */ function claim(uint128 stakeId_) public { require( _stakesByAddress[msg.sender].contains(stakeId_), INVALID_STAKING_ID ); Stake memory currentStake = _stakes[stakeId_]; require(currentStake.lockedUntil < block.timestamp, NOT_OVER); uint256 unwrappedStakeAmount = uint256(currentStake.amount) * 1e18; uint256 totalAmount = _calcReward( currentStake.amount, currentStake.shares, _totalShares, currentStake.interval ) + unwrappedStakeAmount; _totalShares -= currentStake.shares; totalStakes -= currentStake.amount; _stakesByAddress[msg.sender].remove(stakeId_); delete _stakes[stakeId_]; _udsToken.safeTransfer(msg.sender, totalAmount); emit StakeClaimed(msg.sender, stakeId_, totalAmount); } /** * @dev Returns staking by ID. * @param stakeId_ Staking ID. */ function getStake(uint128 stakeId_) public view returns (Stake memory) { return _stakes[stakeId_]; } /** * @dev Returns all staking IDs by stake holder address. * @param stakeholder_ Address of stake holder. */ function getStakesOf( address stakeholder_ ) public view returns (uint256[] memory) { return _stakesByAddress[stakeholder_].values(); } /** * @dev Returns shares for the staking by ID. * @param stakeId_ Staking ID. */ function sharesOf(uint128 stakeId_) public view returns (uint128) { return _stakes[stakeId_].shares; } /** * @dev Returns the reward size for the specified staking ID under current conditions. * @param stakeId_ Staking ID. */ function rewardOf(uint128 stakeId_) public view returns (uint256) { Stake memory currentStake = _stakes[stakeId_]; require(currentStake.lockedUntil < block.timestamp, NOT_OVER); require(currentStake.amount > 0, NOT_EXISTS); return _calcReward( currentStake.amount, currentStake.shares, _totalShares, currentStake.interval ); } /** * @dev Calculates the reward based on the staking amount and interval. * @param stakeAmount_ Number of tokens for staking. Specified without decimal places. * @param interval_ Time interval index 0-5 (see getMonthIntervals()). */ function estimateReward( uint64 stakeAmount_, uint8 interval_ ) public view returns (uint256) { require(stakeAmount_ > 0, ZERO_AMOUNT); require(interval_ < 6, INVALID_INTERVAL); uint128 shares = _intervalCoefficient[interval_] * stakeAmount_ * 100; return _calcReward(stakeAmount_, shares, _totalShares + shares, interval_); } /** * @dev Calculates the reward based on the staking amount, interval and zombie level. * @param stakeAmount_ Number of tokens for staking. Specified without decimal places. * @param interval_ Time interval index 0-5 (see getMonthIntervals()). * @param zombieLevel_ Zombie level. */ function estimateRewardForZombieOwner( uint64 stakeAmount_, uint8 interval_, uint8 zombieLevel_ ) public view returns (uint256) { require(stakeAmount_ > 0, ZERO_AMOUNT); require(interval_ < 6, INVALID_INTERVAL); require(zombieLevel_ < 5, INVALID_ZOMBIE_LEVEL); uint128 shares = _boosterCoefficient[zombieLevel_] * _intervalCoefficient[interval_] * stakeAmount_; return _calcReward(stakeAmount_, shares, _totalShares + shares, interval_); } /** * @dev Returns total staked amount. */ function getTotalStakes() public view returns (uint256) { return uint256(totalStakes) * 1e18; } /** * @dev Returns total staked shares. */ function getTotalShares() public view returns (uint256) { return _totalShares; } /** * @dev Returns current reward pool for stake holder. */ function getCurrentRewardsPool() public view returns (uint256) { return _udsToken.balanceOf(address(this)) - (uint256(totalStakes) * 1e18); } /** * @dev Returns an array of staking intervals specified in months (1 month == 30 days). */ function getMonthIntervals() public view returns (uint128[6] memory) { return _intervalsMonth; } /** * @dev Returns boost coefficients for staking time in accordance with the interval. */ function getIntervalCoefficients() public view returns (uint128[6] memory) { return _intervalCoefficient; } /** * @dev Returns boost coefficients for zombie ownership in accordance with the zombie level. */ function getBoostCoefficients() public view returns (uint128[5] memory) { return _boosterCoefficient; } /** * @dev Returns APR limit for rewards. */ function getMaxApr() public view returns (uint256) { return _maxAPR; } function _getBoostByRank( uint16 zombieRank_ ) private view returns (uint128) { if (zombieRank_ <= 1150) { return _boosterCoefficient[0]; } else if (zombieRank_ <= 1270) { return _boosterCoefficient[1]; } else if (zombieRank_ <= 1390) { return _boosterCoefficient[2]; } else if (zombieRank_ <= 1490) { return _boosterCoefficient[3]; } else { return _boosterCoefficient[4]; } } function _stake( uint64 stakeAmount_, uint8 interval_, uint128 boostCoefficient_, uint256 zombieId_ ) private { require(stakeAmount_ > 0, ZERO_AMOUNT); require(interval_ < 6, INVALID_INTERVAL); uint128 shares = boostCoefficient_ * _intervalCoefficient[interval_] * stakeAmount_; ++_counter; uint128 stakeId = _counter; _stakesByAddress[msg.sender].add(stakeId); _stakes[stakeId] = Stake({ amount: stakeAmount_, shares: shares, lockedUntil: uint40( block.timestamp + (_intervalsMonth[interval_] * 30 * 1 days) ), interval: interval_ }); totalStakes += stakeAmount_; _totalShares += shares; uint256 unwrappedAmount = uint256(stakeAmount_) * 1e18; _udsToken.safeTransferFrom(msg.sender, address(this), unwrappedAmount); emit StakeAdded(msg.sender, stakeId, zombieId_, boostCoefficient_); } function _setMaxApr(uint32 maxAPR_) private { _maxAPR = maxAPR_; emit MaxAprUpdated(maxAPR_); } function _setCoefficients( uint128[6] memory intervalCoefficients_, uint128[5] memory boosterCoefficients_ ) private { for (uint256 i; i < 6; ++i) { require(intervalCoefficients_[i] > 0, INVALID_INPUT); } for (uint256 i; i < 5; ++i) { require(boosterCoefficients_[i] > 0, INVALID_INPUT); } _intervalCoefficient = intervalCoefficients_; _boosterCoefficient = boosterCoefficients_; emit CoefficientsUpdated(intervalCoefficients_, boosterCoefficients_); } function _calcReward( uint128 stakeAmount_, uint128 shares_, uint128 totalShares_, uint8 interval_ ) private view returns (uint256) { uint256 rewardPool = _udsToken.balanceOf(address(this)) - (uint256(totalStakes) * 1e18); uint256 rewards = rewardPool * shares_ / totalShares_; uint256 maxRewards = (_maxAPR * stakeAmount_ * 1e18 * _intervalsMonth[interval_]) / 120000; return rewards < maxRewards ? rewards : maxRewards; } }
Address.sol 244 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
GuardExtension.sol 30 lines
// SPDX-License-Identifier: PROPRIERTARY // Author: Ilya A. Shlyakhovoy // Email: [email protected] pragma solidity 0.8.17; import "./interfaces/IRights.sol"; import "../utils/Guard.sol"; abstract contract GuardExtension is Guard { IRights private _rightsContract; string private constant SAME_VALUE = "Guard: same value"; string private constant ZERO_ADDRESS = "Guard: zero address"; constructor(address rights_) { require(rights_ != address(0), ZERO_ADDRESS); _rightsContract = IRights(rights_); } function _rights() internal view virtual override returns (IRights) { return _rightsContract; } function setRights(address rights_) external virtual override haveRights { require(address(_rightsContract) != rights_, SAME_VALUE); require(rights_ != address(0), ZERO_ADDRESS); _rightsContract = IRights(rights_); } }
IERC20.sol 78 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
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 amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` 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 amount) external returns (bool);
}
IRights.sol 61 lines
// SPDX-License-Identifier: PROPRIERTARY // Author: Ilya A. Shlyakhovoy // Email: [email protected] pragma solidity 0.8.17; interface IRights { event AdminAdded(address indexed admin); event AdminDefined(address indexed admin, address indexed contractHash); event AdminRemoved(address indexed admin); event AdminCleared(address indexed admin, address indexed contractHash); /** @notice Add a new admin for the Rigths contract @param admin_ New admin address */ function addAdmin(address admin_) external; /** @notice Add a new admin for the any other contract @param contract_ Contract address packed into address @param admin_ New admin address */ function addAdmin(address contract_, address admin_) external; /** @notice Remove the existing admin from the Rigths contract @param admin_ Admin address */ function removeAdmin(address admin_) external; /** @notice Remove the existing admin from the specified contract @param contract_ Contract address packed into address @param admin_ Admin address */ function removeAdmin(address contract_, address admin_) external; /** @notice Get the rights for the contract for the caller @param contract_ Contract address packed into address @return have rights or not */ function haveRights(address contract_) external view returns (bool); /** @notice Get the rights for the contract @param contract_ Contract address packed into address @param admin_ Admin address @return have rights or not */ function haveRights(address contract_, address admin_) external view returns (bool); }
IERC721.sol 132 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
IStaking.sol 20 lines
// SPDX-License-Identifier: PROPRIERTARY // Author: Dmitry Kharlanchuk // Email: [email protected] pragma solidity 0.8.17; interface IStaking { event StakeAdded(address indexed staker, uint128 indexed stakeId, uint256 zombieId, uint128 boostCoefficient); event StakeClaimed(address indexed staker, uint128 indexed stakeId, uint256 totalAmount); event CoefficientsUpdated(uint128[6] intervalCoefficients, uint128[5] boosterCoefficients); event MaxAprUpdated(uint32 maxAPR_); struct Stake { uint64 amount; uint128 shares; uint40 lockedUntil; uint8 interval; } }
IActors.sol 173 lines
// SPDX-License-Identifier: PROPRIERTARY // Author: Ilya A. Shlyakhovoy // Email: [email protected] pragma solidity 0.8.17; import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; import {Structures} from "../../lib/Structures.sol"; interface IActors is IERC721Metadata { event Minted(address indexed owner, uint256 indexed id); event MintedImmaculate(address indexed owner, uint256 indexed id); event TokenUriDefined(uint256 indexed id, string kidUri, string adultUri); event ActorWasBorn(uint256 indexed id, uint256 bornTime); /** @notice Get a total amount of issued tokens @return The number of tokens minted */ function total() external view returns (uint256); /** @notice Set an uri for the adult token (only for non immaculate) @param id_ token id @param adultHash_ ipfs hash of the kids metadata */ function setMetadataHash(uint256 id_, string calldata adultHash_) external; /** @notice Set an uri for the adult and kid token (only for immaculate) @param id_ token id @param kidHash_ ipfs hash of the kids metadata @param adultHash_ ipfs hash of the adult metadata */ function setMetadataHashes( uint256 id_, string calldata kidHash_, string calldata adultHash_ ) external; /** @notice Get an uri for the kid token @param id_ token id @return Token uri for the kid actor */ function tokenKidURI(uint256 id_) external view returns (string memory); /** @notice Get an uri for the adult token @param id_ token id @return Token uri for the adult actor */ function tokenAdultURI(uint256 id_) external view returns (string memory); /** @notice Create a new person token (not born yet) @param id_ The id of new minted token @param owner_ Owner of the token @param props_ Array of the actor properties @param sex_ The person sex (true = male, false = female) @param born_ Is the child born or not @param adultTime_ When child become adult actor, if 0 actor is not born yet @param childs_ The amount of childs can be born (only for female) @param immaculate_ True only for potion-breeded @return The new id */ function mint( uint256 id_, address owner_, uint16[10] memory props_, bool sex_, bool born_, uint256 adultTime_, uint8 childs_, bool immaculate_ ) external returns (uint256); /** @notice Get the person props @param id_ Person token id @return Array of the props */ function getProps(uint256 id_) external view returns (uint16[10] memory); /** @notice Get the actor @param id_ Person token id @return Structures.ActorData full struct of actor */ function getActor(uint256 id_) external view returns (Structures.ActorData memory); /** @notice Get the person sex @param id_ Person token id @return true = male, false = female */ function getSex(uint256 id_) external view returns (bool); /** @notice Get the person childs @param id_ Person token id @return childs and possible available childs */ function getChilds(uint256 id_) external view returns (uint8, uint8); /** @notice Breed a child @param id_ Person token id */ function breedChild(uint256 id_) external; /** @notice Get the person immaculate status @param id_ Person token id */ function getImmaculate(uint256 id_) external view returns (bool); /** @notice Get the person born time @param id_ Person token id @return 0 = complete adult, or amount of tokens needed to be paid for */ function getBornTime(uint256 id_) external view returns (uint256); /** @notice Get the person born state @param id_ Person token id @return true = person is born */ function isBorn(uint256 id_) external view returns (bool); /** @notice Birth the person @param id_ Person token id @param adultTime_ When person becomes adult */ function born(uint256 id_, uint256 adultTime_) external; /** @notice Get the person adult timestamp @param id_ Person token id @return timestamp */ function getAdultTime(uint256 id_) external view returns (uint256); /** @notice Grow the @param id_ Person token id @param time_ the deadline to grow */ function setAdultTime(uint256 id_, uint256 time_) external; /** @notice Get the person adult state @param id_ Person token id @return true = person is adult (price is 0 and current date > person's grow deadline) */ function isAdult(uint256 id_) external view returns (bool); /** @notice Get the person rank @param id_ Person token id @return person rank value */ function getRank(uint256 id_) external view returns (uint16); }
SafeERC20.sol 143 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
IERC165.sol 25 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
EnumerableSet.sol 378 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```solidity
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping(bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastValue;
// Update the index for the moved value
set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
}
IERC20Permit.sol 60 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
IERC721Metadata.sol 27 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Metadata is IERC721 {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}
Read Contract
estimateReward 0xbb6c191a → uint256
estimateRewardForZombieOwner 0x8694af78 → uint256
getBoostCoefficients 0xfe7f3b51 → uint128[5]
getCurrentRewardsPool 0xf8c70387 → uint256
getIntervalCoefficients 0x7785c0b6 → uint128[6]
getMaxApr 0x710dc957 → uint256
getMonthIntervals 0xdcb6f638 → uint128[6]
getStake 0x8a3a8b29 → tuple
getStakesOf 0xfafc08c4 → uint256[]
getTotalShares 0xd5002f2e → uint256
getTotalStakes 0x68c33627 → uint256
rewardOf 0xc0f1d8c6 → uint256
sharesOf 0x9e5d82b9 → uint128
Write Contract 6 functions
These functions modify contract state and require a wallet transaction to execute.
claim 0x60e72adb
uint128 stakeId_
setCoefficients 0x0dd3930d
uint128[6] intervalCoefficients_
uint128[5] boosterCoefficients_
setMaxApr 0x361652c9
uint32 maxAPR_
setRights 0x37d2aae9
address rights_
stake 0x55b43fe1
uint64 stakeAmount_
uint8 interval_
stakeByZombieOwner 0xbb87d2aa
uint64 stakeAmount_
uint8 interval_
uint256 zombieId_
Recent Transactions
No transactions found for this address