Address Contract Verified
Address
0xACb8D462Ad11374AbFFaDf2C3a1C145D0673ce56
Balance
0 ETH
Nonce
1
Code Size
17529 bytes
Creator
0x752dfb1C...d126 at tx 0x17f2452a...3aedaa
Indexed Transactions
0
Contract Bytecode
17529 bytes
0x608060405234801561001057600080fd5b50600436106103a45760003560e01c8063766d7cfb116101e9578063d5f9464e1161010f578063e30c3978116100ad578063f6d4c1851161007c578063f6d4c18514610b18578063f7c618c114610b20578063f8cf31cb14610b28578063fecedb6514610b4e576103a4565b8063e30c397814610ace578063e78c1b1b14610ad6578063f24e534314610af3578063f54ac4c114610afb576103a4565b8063d94f11be116100e9578063d94f11be14610a7e578063da38f3af14610a9b578063e0e2f31014610aa3578063e2bbb15814610aab576103a4565b8063d5f9464e14610a27578063d895745c14610a44578063d8fd5a7a14610a61576103a4565b80639b80d28111610187578063bd48cf2211610156578063bd48cf2214610a07578063c0bccbfb14610a0f578063c0db888714610a17578063c1ddfb0014610a1f576103a4565b80639b80d28114610999578063b5bda70d146109a1578063bb872b4a146109be578063bcabf89b146109db576103a4565b80638da5cb5b116101c35780638da5cb5b146108b95780638dbb1e3a146108dd57806393f1a40b1461090057806398969e821461096d576103a4565b8063766d7cfb146108945780638aa28550146103fb5780638ae39cac146108b1576103a4565b806342a9026a116102ce57806352e0371c1161026c578063648b8c6b1161023b578063648b8c6b1461078057806369914d621461079f5780636e2cba99146107c057806373cb07d814610868576103a4565b806352e0371c146106f45780635312ea8e14610730578063630b5ba11461074d57806364482f7914610755576103a4565b8063488a8f58116102a8578063488a8f58146106a157806348cd4cb1146106c75780634e71e0c8146106cf57806351eb05a6146106d7576103a4565b806342a9026a14610644578063441a3e70146106615780634638cef514610684576103a4565b806311ea3264116103465780631eaaa045116103155780631eaaa0451461055d57806321ab46c8146105915780632f380b35146105c257806340be7bec14610621576103a4565b806311ea32641461050957806317caf6f11461052c5780631a249f5c146105345780631aed655314610555576103a4565b80630fa6b3a0116103825780630fa6b3a0146104035780630fc035df146104265780631069f3b51461044957806311aedfbc14610501576103a4565b8063078dfbe7146103a9578063081e3eda146103e157806309cfb6b9146103fb575b600080fd5b6103df600480360360608110156103bf57600080fd5b506001600160a01b03813516906020810135151590604001351515610b56565b005b6103e9610c80565b60408051918252519081900360200190f35b6103e9610c86565b6103df6004803603604081101561041957600080fd5b5080359060200135610c8b565b6103df6004803603604081101561043c57600080fd5b5080359060200135610f39565b6104756004803603604081101561045f57600080fd5b50803590602001356001600160a01b0316611243565b604051808a815260200189815260200188815260200187815260200180602001868152602001858152602001848152602001838152602001828103825287818151815260200191508051906020019060200280838360005b838110156104e55781810151838201526020016104cd565b505050509050019a505050505050505050505060405180910390f35b6103e9611329565b6103df6004803603604081101561051f57600080fd5b508035906020013561132f565b6103e9611580565b6103df6004803603602081101561054a57600080fd5b503561ffff16611586565b6103e96115eb565b6103df6004803603606081101561057357600080fd5b508035906001600160a01b03602082013516906040013515156115f1565b6105ae600480360360208110156105a757600080fd5b50356117bc565b604080519115158252519081900360200190f35b6105df600480360360208110156105d857600080fd5b50356117d1565b604080516001600160a01b0390981688526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190f35b6103df6004803603604081101561063757600080fd5b50803590602001356118d3565b6103df6004803603602081101561065a57600080fd5b50356119fa565b6103df6004803603604081101561067757600080fd5b5080359060200135611b31565b6103df6004803603602081101561069a57600080fd5b5035611dff565b6103df600480360360208110156106b757600080fd5b50356001600160a01b0316611e51565b6103e9611ecb565b6103df611ed1565b6103df600480360360208110156106ed57600080fd5b5035611f93565b6103df6004803603608081101561070a57600080fd5b508035906001600160a01b03602082013581169160408101359091169060600135612054565b6103df6004803603602081101561074657600080fd5b503561230f565b6103df61244c565b6103df6004803603606081101561076b57600080fd5b5080359060208101359060400135151561246f565b61078861252f565b6040805161ffff9092168252519081900360200190f35b6103df600480360360208110156107b557600080fd5b503561ffff1661253f565b6103df600480360360408110156107d657600080fd5b81359190810190604081016020820135600160201b8111156107f757600080fd5b82018360208201111561080957600080fd5b803590602001918460208302840111600160201b8311171561082a57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506125ac945050505050565b6103e96004803603604081101561087e57600080fd5b50803590602001356001600160a01b0316612827565b6103df600480360360208110156108aa57600080fd5b5035612974565b6103e96129c6565b6108c16129cc565b604080516001600160a01b039092168252519081900360200190f35b6103e9600480360360408110156108f357600080fd5b50803590602001356129db565b61092c6004803603604081101561091657600080fd5b50803590602001356001600160a01b0316612a41565b604080519889526020890197909752878701959095526060870193909352608086019190915260a085015260c084015260e083015251908190036101000190f35b6103e96004803603604081101561098357600080fd5b50803590602001356001600160a01b0316612a96565b6103e9612bd5565b6103e9600480360360208110156109b757600080fd5b5035612bdb565b6103df600480360360208110156109d457600080fd5b5035612bf0565b6103e9600480360360408110156109f157600080fd5b50803590602001356001600160a01b0316612c42565b6103e9612d50565b6103e9612d56565b6103e9612f16565b6108c16130d8565b6103df60048036036020811015610a3d57600080fd5b50356130ee565b6103df60048036036020811015610a5a57600080fd5b5035613140565b6103df60048036036020811015610a7757600080fd5b5035613192565b6103df60048036036020811015610a9457600080fd5b50356131e4565b6103e9613433565b6103e9613439565b6103df60048036036040811015610ac157600080fd5b508035906020013561343f565b6108c1613627565b6103df60048036036020811015610aec57600080fd5b5035613636565b6108c1613706565b6103df60048036036020811015610b1157600080fd5b5035613715565b610788613767565b6108c1613771565b6103df60048036036020811015610b3e57600080fd5b50356001600160a01b0316613780565b6108c16137ef565b6000546001600160a01b03163314610ba3576040805162461bcd60e51b815260206004820181905260248201526000805160206143fa833981519152604482015290519081900360640190fd5b8115610c5f576001600160a01b038316151580610bbd5750805b610c06576040805162461bcd60e51b81526020600482015260156024820152744f776e61626c653a207a65726f206164647265737360581b604482015290519081900360640190fd5b600080546040516001600160a01b03808716939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b038516179055610c7b565b600180546001600160a01b0319166001600160a01b0385161790555b505050565b60085490565b600a81565b600060088381548110610c9a57fe5b60009182526020808320868452600a825260408085203386529092529220600481015460069092029092019250610cf2576040805162461bcd60e51b8152602060048201526000602482015290519081900360640190fd5b6004810154831115610d25576040805162461bcd60e51b8152602060048201526000602482015290519081900360640190fd5b6004810154610d3385611f93565b610d3d85336137fe565b60015b848111610db357600081830390506000846004018281548110610d5f57fe5b90600052602060002001549050610d768882613967565b84600401805480610d8357fe5b60008281526020812082016000199081019190915590810190915560048701805490910190555050600101610d40565b5042600683015560006007830181905560058301819055858152601260205260409020546004830154610f0a57825460018401819055600084556005850154610dfb91613a50565b60058501556000805b82811015610e52576000888152601260205260409020805482908110610e2657fe5b6000918252602090912001546001600160a01b0316331415610e4a57809150610e52565b600101610e04565b50600087815260126020526040902080546000198401908110610e7157fe5b60009182526020808320909101548983526012909152604090912080546001600160a01b039092169183908110610ea457fe5b600091825260208083209190910180546001600160a01b0319166001600160a01b039490941693909317909255888152601290915260409020805480610ee657fe5b600082815260209020810160001990810180546001600160a01b0319169055019055505b60155460038501548454610f299291610f239190613a99565b90613af2565b8360020181905550505050505050565b600060088381548110610f4857fe5b60009182526020808320868452600a825260408085203386529092529220600481015460069092029092019250610fa0576040805162461bcd60e51b8152602060048201526000602482015290519081900360640190fd5b6004810154610fae85611f93565b610fb885336137fe565b600080805b83811015610ffa57846004018181548110610fd457fe5b9060005260206000200154871415610ff25780915060019250610ffa565b600101610fbd565b508161104d576040805162461bcd60e51b815260206004820152601960248201527f6e6f7420666f756e6420626f6f7374656420746f6b656e496400000000000000604482015290519081900360640190fd5b6110578787613967565b83600401600184038154811061106957fe5b906000526020600020015484600401828154811061108357fe5b6000918252602090912001556004840180548061109c57fe5b6000828152602080822083016000199081018390559283019093556004808901805490930190925542600688015560078701819055600587018190558981526012909252604090912054908501546112185784546001860181905560008655600587015461110991613a50565b60058701556000805b828110156111605760008a815260126020526040902080548290811061113457fe5b6000918252602090912001546001600160a01b031633141561115857809150611160565b600101611112565b5060008981526012602052604090208054600019840190811061117f57fe5b60009182526020808320909101548b83526012909152604090912080546001600160a01b0390921691839081106111b257fe5b600091825260208083209190910180546001600160a01b0319166001600160a01b0394909416939093179092558a81526012909152604090208054806111f457fe5b600082815260209020810160001990810180546001600160a01b0319169055019055505b601554600387015486546112319291610f239190613a99565b85600201819055505050505050505050565b60008060008060606000806000806000600a60008d815260200190815260200160002060008c6001600160a01b03166001600160a01b03168152602001908152602001600020905080600001548160010154826002015483600301548460040185600501548660060154876007015488600801548480548060200260200160405190810160405280929190818152602001828054801561130257602002820191906000526020600020905b8154815260200190600101908083116112ee575b50505050509450995099509950995099509950995099509950509295985092959850929598565b60115481565b6000828152600a6020908152604080832033845290915290206001810154815401611393576040805162461bcd60e51b815260206004820152600f60248201526e6e6f207374616b6520746f6b656e7360881b604482015290519081900360640190fd5b600f5460048201546201000090910461ffff1690830111156113b457600080fd5b6000600884815481106113c357fe5b600091825260209091206004840154600690920201915061140d5760008481526012602090815260408220805460018101825590835291200180546001600160a01b031916331790555b600f54604080516370a0823160e01b81523360048201529051600092600160201b90046001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561145f57600080fd5b505afa158015611473573d6000803e3d6000fd5b505050506040513d602081101561148957600080fd5b505190508084111561149a57600080fd5b6114a385611f93565b6114ad85336137fe565b60005b8481101561155457600f5460408051632f745c5960e01b815233600482015260006024820181905291519192600160201b90046001600160a01b031691632f745c5991604480820192602092909190829003018186803b15801561151357600080fd5b505afa158015611527573d6000803e3d6000fd5b505050506040513d602081101561153d57600080fd5b5051905061154b8782613b34565b506001016114b0565b506015546003830154845461156e9291610f239190613a99565b60028401555050426006909101555050565b60135481565b6000546001600160a01b031633146115d3576040805162461bcd60e51b815260206004820181905260248201526000805160206143fa833981519152604482015290519081900360640190fd5b600f805461ffff191661ffff92909216919091179055565b60065481565b6000546001600160a01b0316331461163e576040805162461bcd60e51b815260206004820181905260248201526000805160206143fa833981519152604482015290519081900360640190fd5b801561164c5761164c61244c565b6000601454431161165f57601454611661565b435b6013549091506116719085613ce8565b6013556040805160c0810182526001600160a01b039485168152602081019586529081019182526000606082018181526080830182815260a0840183815260088054600181018255945293517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3600690940293840180546001600160a01b031916919098161790965595517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee482015591517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee583015593517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee682015591517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee78301555090517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee890910155565b60106020526000908152604090205460ff1681565b600080600080600080600080600889815481106117ea57fe5b60009182526020822060069091020180546003549193506001600160a01b039182169116141561181d5750600954611896565b8154604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561186757600080fd5b505afa15801561187b573d6000803e3d6000fd5b505050506040513d602081101561189157600080fd5b505190505b815460018301546002840154600385015460048601546005909601546001600160a01b039094169e949d50919b5099509750919550909350915050565b6000828152600a6020908152604080832033845290915290206001810154815401611937576040805162461bcd60e51b815260206004820152600f60248201526e6e6f207374616b6520746f6b656e7360881b604482015290519081900360640190fd5b600f5460048201546201000090910461ffff166001909101111561195a57600080fd5b60006008848154811061196957fe5b60009182526020909120600484015460069092020191506119b35760008481526012602090815260408220805460018101825590835291200180546001600160a01b031916331790555b6119bc84611f93565b6119c684336137fe565b6119d08484613b34565b601554600382015483546119e99291610f239190613a99565b600283015550426006909101555050565b6000818152600a6020908152604080832033845290915290206011546006820154420311611a67576040805162461bcd60e51b81526020600482015260156024820152746e6f7420656c696769626c6520746f20636c61696d60581b604482015290519081900360640190fd5b600060088381548110611a7657fe5b90600052602060002090600602019050611a8f83611f93565b611a9983336137fe565b60155460038201548354611ab29291610f239190613a99565b600283015560058201546007830154600091611ace9190613a50565b9050611ada3382613d42565b604080518281529051859133917fabcaf0d72be078b7b459a074ead55fd9690a3d35e84441e246cc038b9e6c84659181900360200190a36005830154611b209082613ce8565b600584015550504260069091015550565b600280541415611b88576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60028081905550600060088381548110611b9e57fe5b60009182526020808320868452600a82526040808520338652909252922060018101548154600690930290930193509101831115611c18576040805162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dce881b9bdd0819dbdbd960721b604482015290519081900360640190fd5b600c548160030154420311611c74576040805162461bcd60e51b815260206004820152601860248201527f6e6f7420656c696769626c6520746f2077697468647261770000000000000000604482015290519081900360640190fd5b611c7d84611f93565b611c8784336137fe565b805415611cb5578054611c9a9084613a50565b81556005820154611cab9084613a50565b6005830155611cca565b6001810154611cc49084613a50565b60018201555b60155460038301548254611ce39291610f239190613a99565b6002820155600060078201819055600582015542600682015581546003546001600160a01b0390811691161415611d2557600954611d219084613a50565b6009555b8215611da7576004546001600160a01b03166379cc679033611d4886600a613a99565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611d8e57600080fd5b505af1158015611da2573d6000803e3d6000fd5b505050505b8154611dbd906001600160a01b03163385613f04565b604080518481529051859133917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689181900360200190a3505060016002555050565b6000546001600160a01b03163314611e4c576040805162461bcd60e51b815260206004820181905260248201526000805160206143fa833981519152604482015290519081900360640190fd5b601155565b6000546001600160a01b03163314611e9e576040805162461bcd60e51b815260206004820181905260248201526000805160206143fa833981519152604482015290519081900360640190fd5b600f80546001600160a01b03909216600160201b02640100000000600160c01b0319909216919091179055565b60145481565b6001546001600160a01b0316338114611f31576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c657220213d2070656e64696e67206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b039092166001600160a01b0319928316179055600180549091169055565b600060088281548110611fa257fe5b9060005260206000209060060201905080600201544311611fc35750612051565b6005810154611fd85743600290910155612051565b6000611fe88260020154436129db565b90506000612015601354610f23856001015461200f60075487613a9990919063ffffffff16565b90613a99565b90506120426120378460050154610f2360155485613a9990919063ffffffff16565b600385015490613ce8565b60038401555050436002909101555b50565b6002805414156120ab576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600280556004546001600160a01b031633146120c657600080fd5b6000600885815481106120d557fe5b60009182526020808320888452600a80835260408086206001600160a01b038b81168852945280862093891686528520600694909402909101945090929061211e908690613af2565b9050808360010154846000015401101561217f576040805162461bcd60e51b815260206004820152601760248201527f7472616e73666572206578636565647320616d6f756e74000000000000000000604482015290519081900360640190fd5b600c5483600301544203116121db576040805162461bcd60e51b815260206004820152601760248201527f6e6f7420656c696769626c6520746f20756e6474616b65000000000000000000604482015290519081900360640190fd5b6121e488611f93565b6121ee88886137fe565b8254156122085782546122019082613a50565b835561221d565b60018301546122179082613a50565b60018401555b601554600385015484546122369291610f239190613a99565b600284015542600684015560006007840181905560058401819055600383015461225f90613f56565b905060006122738460040180549050613f74565b905081801561227f5750805b1561228e5761228e8a896137fe565b80156122be57600184015484546122b09185916122aa91613ce8565b90613ce8565b8455600060018501556122d3565b60018401546122cd9084613ce8565b60018501555b601554600387015485546122ec9291610f239190613a99565b600280860191909155426006909501949094555050600190915550505050505050565b600280541415612366576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002808190555060006008828154811061237c57fe5b60009182526020808320858452600a825260408085203380875293529093206001810154815460069094029094019450926123cc926123ba91613ce8565b84546001600160a01b03169190613f04565b80546040805191825251849133917fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959181900360200190a3805415612421578054600583015461241b91613a50565b60058301555b6000808255600180830182905560028084018390556005840183905560079093019190915590555050565b60085460005b8181101561246b5761246381611f93565b600101612452565b5050565b6000546001600160a01b031633146124bc576040805162461bcd60e51b815260206004820181905260248201526000805160206143fa833981519152604482015290519081900360640190fd5b80156124ca576124ca61244c565b612501826122aa600886815481106124de57fe5b906000526020600020906006020160010154601354613a5090919063ffffffff16565b601381905550816008848154811061251557fe5b906000526020600020906006020160010181905550505050565b600f5462010000900461ffff1681565b6000546001600160a01b0316331461258c576040805162461bcd60e51b815260206004820181905260248201526000805160206143fa833981519152604482015290519081900360640190fd5b600f805461ffff909216620100000263ffff000019909216919091179055565b8051806125da576040805162461bcd60e51b8152602060048201526000602482015290519081900360640190fd5b6000838152600a602090815260408083203384529091529020600181015481540161263e576040805162461bcd60e51b815260206004820152600f60248201526e6e6f207374616b6520746f6b656e7360881b604482015290519081900360640190fd5b600f54604080516370a0823160e01b81523360048201529051600092600160201b90046001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561269057600080fd5b505afa1580156126a4573d6000803e3d6000fd5b505050506040513d60208110156126ba57600080fd5b50519050806126ea576040805162461bcd60e51b8152602060048201526000602482015290519081900360640190fd5b6000600886815481106126f957fe5b60009182526020909120600485015460069092020191506127435760008681526012602090815260408220805460018101825590835291200180546001600160a01b031916331790555b6004830154600f5462010000900461ffff1603806127a8576040805162461bcd60e51b815260206004820152601960248201527f6f766572666c6f77206d6178696d756d20626f6f7374696e6700000000000000604482015290519081900360640190fd5b808510156127b35750835b6127bc87611f93565b6127c687336137fe565b60005b818110156127f6576127ee888883815181106127e157fe5b6020026020010151613b34565b6001016127c9565b50601554600383015485546128109291610f239190613a99565b600285015550504260069092019190915550505050565b6000806008848154811061283757fe5b60009182526020808320878452600a825260408085206001600160a01b03891686529092529220600360069092029092019081015460028201549193509043118015612887575060008360050154115b156128f157600061289c8460020154436129db565b905060006128c3601354610f23876001015461200f60075487613a9990919063ffffffff16565b90506128ec6128e58660050154610f2360155485613a9990919063ffffffff16565b8490613ce8565b925050505b600482015460009061290290613f8c565b90506000612931846002015461292b601554610f23878960000154613a9990919063ffffffff16565b90613a50565b905060006129446064610f238585613a99565b9050612965816122aa87600501548860070154613a5090919063ffffffff16565b96505050505050505b92915050565b6000546001600160a01b031633146129c1576040805162461bcd60e51b815260206004820181905260248201526000805160206143fa833981519152604482015290519081900360640190fd5b600b55565b60075481565b6000546001600160a01b031681565b600060065482116129fc576129f5600a61200f8486613a50565b905061296e565b6006548310612a0f576129f58284613a50565b6129f5612a2760065484613a5090919063ffffffff16565b6122aa600a61200f87600654613a5090919063ffffffff16565b600a602052816000526040600020602052806000526040600020600091509150508060000154908060010154908060020154908060030154908060050154908060060154908060070154908060080154905088565b60008060088481548110612aa657fe5b60009182526020808320878452600a825260408085206001600160a01b03891686529092529220600360069092029092019081015460028201549193509043118015612af6575060008360050154115b15612b59576000612b0b8460020154436129db565b90506000612b32601354610f23876001015461200f60075487613a9990919063ffffffff16565b9050612b546128e58660050154610f2360155485613a9990919063ffffffff16565b925050505b6004820154600090612b6a90613f8c565b90506000612b93846002015461292b601554610f23878960000154613a9990919063ffffffff16565b90506000612bbf856005015461292b87600701546122aa6064610f23888a613a9990919063ffffffff16565b6008860154909150612965906122aa8484613ce8565b600e5481565b6000818152601260205260409020545b919050565b6000546001600160a01b03163314612c3d576040805162461bcd60e51b815260206004820181905260248201526000805160206143fa833981519152604482015290519081900360640190fd5b600755565b60008060088481548110612c5257fe5b60009182526020808320878452600a825260408085206001600160a01b03891686529092529220600360069092029092019081015460028201549193509043118015612ca2575060008360050154115b15612d05576000612cb78460020154436129db565b90506000612cde601354610f23876001015461200f60075487613a9990919063ffffffff16565b9050612d006128e58660050154610f2360155485613a9990919063ffffffff16565b925050505b6000612d2c836002015461292b601554610f23868860000154613a9990919063ffffffff16565b9050612d45836008015482613ce890919063ffffffff16565b979650505050505050565b600b5481565b60008060005b600854811015612f1057600060088281548110612d7557fe5b9060005260206000209060060201905060008160030154905060005b600084815260126020526040902054811015612f05576000848152600a6020908152604080832060129092528220805483919085908110612dce57fe5b60009182526020808320909101546001600160a01b031683528201929092526040019020600285015490915043118015612e0c575060008460050154115b15612e76576000612e218560020154436129db565b90506000612e48601354610f23886001015461200f60075487613a9990919063ffffffff16565b9050612e71612e6a8760050154610f2360155485613a9990919063ffffffff16565b8690613ce8565b945050505b6004810154600090612e8790613f8c565b90506000612eb0836002015461292b601554610f23898860000154613a9990919063ffffffff16565b90506000612ec36064610f238585613a99565b90506000612ee6826122aa87600501548860070154613a5090919063ffffffff16565b9050612ef28a82613ce8565b99505060019094019350612d9192505050565b505050600101612d5c565b50905090565b60008060005b600854811015612f1057600060088281548110612f3557fe5b9060005260206000209060060201905060008160030154905060005b6000848152601260205260409020548110156130cd576000848152600a6020908152604080832060129092528220805483919085908110612f8e57fe5b60009182526020808320909101546001600160a01b03168352820192909252604001902060115460068201549192504291909103106130c457836002015443118015612fde575060008460050154115b15613041576000612ff38560020154436129db565b9050600061301a601354610f23886001015461200f60075487613a9990919063ffffffff16565b905061303c612e6a8760050154610f2360155485613a9990919063ffffffff16565b945050505b600481015460009061305290613f8c565b9050600061307b836002015461292b601554610f23898860000154613a9990919063ffffffff16565b9050600061308e6064610f238585613a99565b905060006130b1826122aa87600501548860070154613a5090919063ffffffff16565b90506130bd8a82613ce8565b9950505050505b50600101612f51565b505050600101612f1c565b600f54600160201b90046001600160a01b031681565b6000546001600160a01b0316331461313b576040805162461bcd60e51b815260206004820181905260248201526000805160206143fa833981519152604482015290519081900360640190fd5b600e55565b6000546001600160a01b0316331461318d576040805162461bcd60e51b815260206004820181905260248201526000805160206143fa833981519152604482015290519081900360640190fd5b600d55565b6000546001600160a01b031633146131df576040805162461bcd60e51b815260206004820181905260248201526000805160206143fa833981519152604482015290519081900360640190fd5b600c55565b6000600882815481106131f357fe5b60009182526020808320858452600a8252604080852033865290925292206004810154600690920290920192508061324c576040805162461bcd60e51b8152602060048201526000602482015290519081900360640190fd5b61325584611f93565b61325f84336137fe565b60005b8181101561329b57600083600401828154811061327b57fe5b906000526020600020015490506132928682613967565b50600101613262565b506132aa6004830160006143a6565b60048084018054839003905542600684015560006007840181905560058401819055858152601260205260409020549083015461340b578254600184018190556000845560058501546132fc91613a50565b60058501556000805b8281101561335357600087815260126020526040902080548290811061332757fe5b6000918252602090912001546001600160a01b031633141561334b57809150613353565b600101613305565b5060008681526012602052604090208054600019840190811061337257fe5b60009182526020808320909101548883526012909152604090912080546001600160a01b0390921691839081106133a557fe5b600091825260208083209190910180546001600160a01b0319166001600160a01b0394909416939093179092558781526012909152604090208054806133e757fe5b600082815260209020810160001990810180546001600160a01b0319169055019055505b601554600385015484546134249291610f239190613a99565b83600201819055505050505050565b600c5481565b600d5481565b60006008838154811061344e57fe5b60009182526020808320868452600a8252604080852033865290925292206006909102909101915061347f84611f93565b600481015460009061349090613f74565b905061349c85336137fe565b82546134b3906001600160a01b0316333087613fdc565b82546003546001600160a01b03908116911614156134dc576009546134d89085613ce8565b6009555b801561351a57600182015482546134f89186916122aa91613ce8565b825560058301546135099085613ce8565b60058401556000600183015561352f565b60018201546135299085613ce8565b60018301555b601554600384015483546135489291610f239190613a99565b600283015583156135e3576004546001600160a01b03166340c10f193361357087600a613a99565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156135b657600080fd5b505af11580156135ca573d6000803e3d6000fd5b505050506040513d60208110156135e057600080fd5b50505b426006830155604080518581529051869133917f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a159181900360200190a35050505050565b6001546001600160a01b031681565b60006008828154811061364557fe5b60009182526020808320858452600a82526040808520338652909252908320600381015460069093029091019350919061367e90613f56565b90506001811515146136cc576040805162461bcd60e51b81526020600482015260126024820152716e6f7420636c61696d20656c696769626c6560701b604482015290519081900360640190fd5b6136d584611f93565b6136df84336137fe565b601554600384015483546136f89291610f239190613a99565b826002018190555050505050565b6003546001600160a01b031681565b6000546001600160a01b03163314613762576040805162461bcd60e51b815260206004820181905260248201526000805160206143fa833981519152604482015290519081900360640190fd5b601555565b600f5461ffff1681565b6005546001600160a01b031681565b6000546001600160a01b031633146137cd576040805162461bcd60e51b815260206004820181905260248201526000805160206143fa833981519152604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6004546001600160a01b031681565b60006008838154811061380d57fe5b60009182526020808320868452600a825260408085206001600160a01b0388168652909252908320600381015460069093029091019350919061384f90613f56565b600384015460048401549192509060009061386990613f8c565b90506000613892856002015461292b601554610f23878a60000154613a9990919063ffffffff16565b905060006138a56064610f238585613a99565b60078701549091506138b79082613ce8565b600787015560008580156138cb5750600083115b156138f85760088701546138e0908490613ce8565b90506138ec8982613d42565b60006008880155613912565b50600886015460009061390c908490613ce8565b60088801555b6040805182815290518b916001600160a01b038c16917f02f5e52fd5bf7180f6e79766027cc92871fbcd14ae61ee25c0ebbc254b3cf92c9181900360200190a342876003018190555050505050505050505050565b60008181526010602052604090205460ff16151560011461398757600080fd5b600f54604080516323b872dd60e01b8152306004820152336024820152604481018490529051600160201b9092046001600160a01b0316916323b872dd9160648082019260009290919082900301818387803b1580156139e657600080fd5b505af11580156139fa573d6000803e3d6000fd5b505050600082815260106020908152604091829020805460ff191690558151848152915185935033927fd9ccb4973c95d201bc1724ce7e7f19f8e0835e571f58bf8b6a0de82084f0574f92908290030190a35050565b6000613a9283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061403c565b9392505050565b600082613aa85750600061296e565b82820282848281613ab557fe5b0414613a925760405162461bcd60e51b81526004018080602001828103825260218152602001806143d96021913960400191505060405180910390fd5b6000613a9283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506140d3565b60008181526010602052604090205460ff1615613b8a576040805162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e48189bdbdcdd1959608a1b604482015290519081900360640190fd5b600f54604080516323b872dd60e01b8152336004820152306024820152604481018490529051600160201b9092046001600160a01b0316916323b872dd9160648082019260009290919082900301818387803b158015613be957600080fd5b505af1158015613bfd573d6000803e3d6000fd5b5050506000828152601060205260408120805460ff19166001179055600880549192509084908110613c2b57fe5b60009182526020808320868452600a82526040808520338652909252922060018101546006909202909201925015613c805760018101548082556005830154613c7391613ce8565b6005830155600060018201555b600480820180546001818101835560009283526020928390209091018690559184018054909201909155604080518581529051869233927faadc628cb4fd3bb7a62795eb460290459458bdc6f387ffde727c740f42c18337929081900390910190a350505050565b600082820183811015613a92576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600554604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015613d8d57600080fd5b505afa158015613da1573d6000803e3d6000fd5b505050506040513d6020811015613db757600080fd5b50516005546003549192506001600160a01b0391821691161415613ded57600954811115613de9576009549003613ded565b5060005b80821115613e7d576005546040805163a9059cbb60e01b81526001600160a01b038681166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b158015613e4b57600080fd5b505af1158015613e5f573d6000803e3d6000fd5b505050506040513d6020811015613e7557600080fd5b50610c7b9050565b6005546040805163a9059cbb60e01b81526001600160a01b038681166004830152602482018690529151919092169163a9059cbb9160448083019260209291908290030181600087803b158015613ed357600080fd5b505af1158015613ee7573d6000803e3d6000fd5b505050506040513d6020811015613efd57600080fd5b5050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610c7b908490614138565b6000600b548242031115613f6c57506001612beb565b506000919050565b600f5460009061ffff168210613f6c57506001612beb565b600f5460009061ffff168211613fa457506000612beb565b600f54600090613fbf90849061ffff90811660010116613a50565b9050613a92600d546122aa600e5484613a9990919063ffffffff16565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052614036908590614138565b50505050565b600081848411156140cb5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614090578181015183820152602001614078565b50505050905090810190601f1680156140bd5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836141225760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614090578181015183820152602001614078565b50600083858161412e57fe5b0495945050505050565b606061418d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166141e99092919063ffffffff16565b805190915015610c7b578080602001905160208110156141ac57600080fd5b5051610c7b5760405162461bcd60e51b815260040180806020018281038252602a81526020018061441a602a913960400191505060405180910390fd5b60606141f88484600085614200565b949350505050565b606061420b8561436d565b61425c576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b6020831061429b5780518252601f19909201916020918201910161427c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146142fd576040519150601f19603f3d011682016040523d82523d6000602084013e614302565b606091505b509150915081156143165791506141f89050565b8051156143265780518082602001fd5b60405162461bcd60e51b8152602060048201818152865160248401528651879391928392604401919085019080838360008315614090578181015183820152602001614078565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906141f8575050151592915050565b508054600082559060005260206000209081019061205191905b808211156143d457600081556001016143c0565b509056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220a9081b7793282bba903f53d039cf7e5766ca637d5e33d8084c526a5a2b993ee564736f6c634300060c0033
Verified Source Code Full Match
Compiler: v0.6.12+commit.27d51765
EVM: istanbul
Optimization: Yes (200 runs)
StrikeBoostFarm.sol 947 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;
import "./interfaces/IBoostToken.sol";
import "./interfaces/IStrikeBoostFarm.sol";
import "./interfaces/IERC721Receiver.sol";
import "./interfaces/IERC20.sol";
import "./interfaces/IVStrike.sol";
import "./libraries/SafeERC20.sol";
import "./libraries/EnumerableSet.sol";
import "./libraries/SafeMath.sol";
import "./libraries/Ownable.sol";
import "./libraries/ReentrancyGuard.sol";
// StrikeFarm is the master of Farm.
//
// Note that it's ownable and the owner wields tremendous power. The ownership
// will be transferred to a governance smart contract once STRIKE is sufficiently
// distributed and the community can show to govern itself.
//
// Have fun reading it. Hopefully it's bug-free. God bless.
contract StrikeBoostFarm is IStrikeBoostFarm, Ownable, ReentrancyGuard {
using SafeMath for uint256;
using SafeERC20 for IERC20;
// Info of each user.
struct UserInfo {
uint256 amount; // How many LP tokens the user has provided.
uint256 pendingAmount; // non-eligible lp amount for reward
uint256 rewardDebt; // Reward debt. See explanation below.
uint256 depositedDate; // Latest deposited date
//
// We do some fancy math here. Basically, any point in time, the amount of STRIKEs
// entitled to a user but is pending to be distributed is:
//
// pending reward = (user.amount * pool.accRewardPerShare) - user.rewardDebt
//
// Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:
// 1. The pool's `accRewardPerShare` (and `lastRewardBlock`) gets updated.
// 2. User receives the pending reward sent to his/her address.
// 3. User's `amount` gets updated.
// 4. User's `rewardDebt` gets updated.
uint256[] boostFactors;
uint256 boostRewardDebt; // Boost Reward debt. See explanation below.
uint256 boostedDate; // Latest boosted date
uint256 accBoostReward;
uint256 accBaseReward;
}
// Info of each pool.
struct PoolInfo {
IERC20 lpToken; // Address of LP token contract.
uint256 allocPoint; // How many allocation points assigned to this pool. STRIKEs to distribute per block.
uint256 lastRewardBlock; // Last block number that STRIKEs distribution occurs.
uint256 accRewardPerShare; // Accumulated STRIKEs per share, times 1e12. See below.
uint256 totalBoostCount; // Total valid boosted accounts count.
uint256 rewardEligibleSupply; // total LP supply of users which staked boost token.
}
// The STRIKE TOKEN!
address public strk;
// The vSTRIKE TOKEN!
address public vStrk;
// The Reward TOKEN!
address public rewardToken;
// Block number when bonus STRIKE period ends.
uint256 public bonusEndBlock;
// STRIKE tokens created per block.
uint256 public rewardPerBlock;
// Bonus muliplier for early STRIKEex makers.
uint256 public constant BONUS_MULTIPLIER = 10;
// VSTRIKE minting rate
uint256 public constant VSTRK_RATE = 10;
// Info of each pool.
PoolInfo[] private poolInfo;
// Total STRIKE amount deposited in STRIKE single pool. To reduce tx-fee, not included in struct PoolInfo.
uint256 private lpSupplyOfStrikePool;
// Info of each user that stakes LP tokens.
mapping(uint256 => mapping(address => UserInfo)) public userInfo;
// claimable time limit for base reward
uint256 public claimBaseRewardTime = 1 days;
uint256 public unstakableTime = 2 days;
uint256 public initialBoostMultiplier = 20;
uint256 public boostMultiplierFactor = 10;
// Boosting Part
// Minimum vaild boost NFT count
uint16 public minimumValidBoostCount = 1;
// Maximum boost NFT count
uint16 public maximumBoostCount = 20;
// NFT contract for boosting
IBoostToken public boostFactor;
// Boosted with NFT or not
mapping (uint256 => bool) public isBoosted;
// claimable time limit for boost reward
uint256 public claimBoostRewardTime = 30 days;
// boosted user list
mapping(uint256 => address[]) private boostedUsers;
// Total allocation poitns. Must be the sum of all allocation points in all pools.
uint256 public totalAllocPoint = 0;
// The block number when STRIKE mining starts.
uint256 public startBlock;
uint256 private accMulFactor = 1e12;
event Deposit(address indexed user, uint256 indexed pid, uint256 amount);
event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);
event EmergencyWithdraw(
address indexed user,
uint256 indexed pid,
uint256 amount
);
event ClaimBaseRewards(
address indexed user,
uint256 indexed pid,
uint256 amount
);
event ClaimBoostRewards(
address indexed user,
uint256 indexed pid,
uint256 amount
);
event Boost(address indexed user, uint256 indexed pid, uint256 tokenId);
event UnBoost(address indexed user, uint256 indexed pid, uint256 tokenId);
constructor(
address _strk,
address _rewardToken,
address _vStrk,
address _boost,
uint256 _rewardPerBlock,
uint256 _startBlock,
uint256 _bonusEndBlock
) public {
strk = _strk;
rewardToken = _rewardToken;
vStrk = _vStrk;
boostFactor = IBoostToken(_boost);
rewardPerBlock = _rewardPerBlock;
bonusEndBlock = _bonusEndBlock;
startBlock = _startBlock;
}
function poolLength() external view returns (uint256) {
return poolInfo.length;
}
function getPoolInfo(uint _pid) external view returns (
IERC20 lpToken,
uint256 lpSupply,
uint256 allocPoint,
uint256 lastRewardBlock,
uint accRewardPerShare,
uint totalBoostCount,
uint256 rewardEligibleSupply
) {
PoolInfo storage pool = poolInfo[_pid];
uint256 amount;
if (strk == address(pool.lpToken)) {
amount = lpSupplyOfStrikePool;
} else {
amount = pool.lpToken.balanceOf(address(this));
}
return (
pool.lpToken,
amount,
pool.allocPoint,
pool.lastRewardBlock,
pool.accRewardPerShare,
pool.totalBoostCount,
pool.rewardEligibleSupply
);
}
function getUserInfo(uint256 _pid, address _user) external view returns(
uint256 amount,
uint256 pendingAmount,
uint256 rewardDebt,
uint256 depositedDate,
uint256[] memory boostFactors,
uint256 boostRewardDebt,
uint256 boostedDate,
uint256 accBoostReward,
uint256 accBaseReward
) {
UserInfo storage user = userInfo[_pid][_user];
return (
user.amount,
user.pendingAmount,
user.rewardDebt,
user.depositedDate,
user.boostFactors,
user.boostRewardDebt,
user.boostedDate,
user.accBoostReward,
user.accBaseReward
);
}
// Add a new lp to the pool. Can only be called by the owner.
// XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.
function add(
uint256 _allocPoint,
IERC20 _lpToken,
bool _withUpdate
) public onlyOwner {
if (_withUpdate) {
massUpdatePools();
}
uint256 lastRewardBlock =
block.number > startBlock ? block.number : startBlock;
totalAllocPoint = totalAllocPoint.add(_allocPoint);
poolInfo.push(
PoolInfo({
lpToken: _lpToken,
allocPoint: _allocPoint,
lastRewardBlock: lastRewardBlock,
accRewardPerShare: 0,
totalBoostCount: 0,
rewardEligibleSupply: 0
})
);
}
// Update the given pool's STRIKE allocation point. Can only be called by the owner.
function set(
uint256 _pid,
uint256 _allocPoint,
bool _withUpdate
) public onlyOwner {
if (_withUpdate) {
massUpdatePools();
}
totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(
_allocPoint
);
poolInfo[_pid].allocPoint = _allocPoint;
}
// Update the given STRIKE per block. Can only be called by the owner.
function setRewardPerBlock(
uint256 speed
) public onlyOwner {
rewardPerBlock = speed;
}
// Return reward multiplier over the given _from to _to block.
function getMultiplier(uint256 _from, uint256 _to)
public
view
returns (uint256)
{
if (_to <= bonusEndBlock) {
return _to.sub(_from).mul(BONUS_MULTIPLIER);
} else if (_from >= bonusEndBlock) {
return _to.sub(_from);
} else {
return
bonusEndBlock.sub(_from).mul(BONUS_MULTIPLIER).add(
_to.sub(bonusEndBlock)
);
}
}
function getValidBoostFactors(uint256 userBoostFactors) internal view returns (uint256) {
uint256 validBoostFactors = userBoostFactors > minimumValidBoostCount ? userBoostFactors - minimumValidBoostCount : 0;
return validBoostFactors;
}
function getBoostMultiplier(uint256 boostFactorCount) internal view returns (uint256) {
if (boostFactorCount <= minimumValidBoostCount) {
return 0;
}
uint256 initBoostCount = boostFactorCount.sub(minimumValidBoostCount + 1);
return initBoostCount.mul(boostMultiplierFactor).add(initialBoostMultiplier);
}
// View function to see pending STRIKEs on frontend.
function pendingReward(uint256 _pid, address _user)
external
view
returns (uint256)
{
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_user];
uint256 accRewardPerShare = pool.accRewardPerShare;
if (block.number > pool.lastRewardBlock && pool.rewardEligibleSupply > 0) {
uint256 multiplier =
getMultiplier(pool.lastRewardBlock, block.number);
uint256 reward =
multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(
totalAllocPoint
);
accRewardPerShare = accRewardPerShare.add(
reward.mul(accMulFactor).div(pool.rewardEligibleSupply)
);
}
uint256 boostMultiplier = getBoostMultiplier(user.boostFactors.length);
uint256 baseReward = user.amount.mul(accRewardPerShare).div(accMulFactor).sub(user.rewardDebt);
uint256 boostReward = boostMultiplier.mul(baseReward).div(100).add(user.accBoostReward).sub(user.boostRewardDebt);
return baseReward.add(boostReward).add(user.accBaseReward);
}
// View function to see pending STRIKEs on frontend.
function pendingBaseReward(uint256 _pid, address _user)
external
view
returns (uint256)
{
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_user];
uint256 accRewardPerShare = pool.accRewardPerShare;
if (block.number > pool.lastRewardBlock && pool.rewardEligibleSupply > 0) {
uint256 multiplier =
getMultiplier(pool.lastRewardBlock, block.number);
uint256 reward =
multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(
totalAllocPoint
);
accRewardPerShare = accRewardPerShare.add(
reward.mul(accMulFactor).div(pool.rewardEligibleSupply)
);
}
uint256 newReward = user.amount.mul(accRewardPerShare).div(accMulFactor).sub(user.rewardDebt);
return newReward.add(user.accBaseReward);
}
// Update reward vairables for all pools. Be careful of gas spending!
function massUpdatePools() public {
uint256 length = poolInfo.length;
for (uint256 pid = 0; pid < length; ++pid) {
updatePool(pid);
}
}
// Update reward variables of the given pool to be up-to-date.
function updatePool(uint256 _pid) public {
PoolInfo storage pool = poolInfo[_pid];
if (block.number <= pool.lastRewardBlock) {
return;
}
if (pool.rewardEligibleSupply == 0) {
pool.lastRewardBlock = block.number;
return;
}
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 reward =
multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(
totalAllocPoint
);
pool.accRewardPerShare = pool.accRewardPerShare.add(
reward.mul(accMulFactor).div(pool.rewardEligibleSupply)
);
pool.lastRewardBlock = block.number;
}
// Check the eligible user or not for reward
function checkRewardEligible(uint boost) internal view returns(bool) {
if (boost >= minimumValidBoostCount) {
return true;
}
return false;
}
// Check claim eligible
function checkRewardClaimEligible(uint depositedTime) internal view returns(bool) {
if (block.timestamp - depositedTime > claimBaseRewardTime) {
return true;
}
return false;
}
// Claim base lp reward
function _claimBaseRewards(uint256 _pid, address _user) internal {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_user];
bool claimEligible = checkRewardClaimEligible(user.depositedDate);
uint256 accRewardPerShare = pool.accRewardPerShare;
uint256 boostMultiplier = getBoostMultiplier(user.boostFactors.length);
uint256 baseReward = user.amount.mul(accRewardPerShare).div(accMulFactor).sub(user.rewardDebt);
uint256 boostReward = boostMultiplier.mul(baseReward).div(100);
user.accBoostReward = user.accBoostReward.add(boostReward);
uint256 rewards;
if (claimEligible && baseReward > 0) {
rewards = baseReward.add(user.accBaseReward);
safeRewardTransfer(_user, rewards);
user.accBaseReward = 0;
} else {
rewards = 0;
user.accBaseReward = baseReward.add(user.accBaseReward);
}
emit ClaimBaseRewards(_user, _pid, rewards);
user.depositedDate = block.timestamp;
}
function claimBaseRewards(uint256 _pid) external {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
bool claimEligible = checkRewardClaimEligible(user.depositedDate);
require(claimEligible == true, "not claim eligible");
updatePool(_pid);
_claimBaseRewards(_pid, msg.sender);
user.rewardDebt = user.amount.mul(pool.accRewardPerShare).div(accMulFactor);
}
// Deposit LP tokens to STRIKEswap for STRIKE allocation.
function deposit(uint256 _pid, uint256 _amount) external {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
updatePool(_pid);
bool rewardEligible = checkRewardEligible(user.boostFactors.length);
_claimBaseRewards(_pid, msg.sender);
pool.lpToken.safeTransferFrom(
address(msg.sender),
address(this),
_amount
);
if (strk == address(pool.lpToken)) {
lpSupplyOfStrikePool = lpSupplyOfStrikePool.add(_amount);
}
if (rewardEligible) {
user.amount = user.amount.add(user.pendingAmount).add(_amount);
pool.rewardEligibleSupply = pool.rewardEligibleSupply.add(_amount);
user.pendingAmount = 0;
} else {
user.pendingAmount = user.pendingAmount.add(_amount);
}
user.rewardDebt = user.amount.mul(pool.accRewardPerShare).div(accMulFactor);
if (_amount > 0) {
IVStrike(vStrk).mint(msg.sender, _amount.mul(VSTRK_RATE));
}
user.boostedDate = block.timestamp;
emit Deposit(msg.sender, _pid, _amount);
}
// Withdraw LP tokens from STRIKEexFarm.
function withdraw(uint256 _pid, uint256 _amount) external nonReentrant {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.amount + user.pendingAmount >= _amount, "withdraw: not good");
require(block.timestamp - user.depositedDate > unstakableTime, "not eligible to withdraw");
updatePool(_pid);
_claimBaseRewards(_pid, msg.sender);
if (user.amount > 0) {
user.amount = user.amount.sub(_amount);
pool.rewardEligibleSupply = pool.rewardEligibleSupply.sub(_amount);
} else {
user.pendingAmount = user.pendingAmount.sub(_amount);
}
user.rewardDebt = user.amount.mul(pool.accRewardPerShare).div(accMulFactor);
// will loose unclaimed boost reward
user.accBoostReward = 0;
user.boostRewardDebt = 0;
user.boostedDate = block.timestamp;
if (strk == address(pool.lpToken)) {
lpSupplyOfStrikePool = lpSupplyOfStrikePool.sub(_amount);
}
if (_amount > 0) {
IVStrike(vStrk).burnFrom(msg.sender, _amount.mul(VSTRK_RATE));
}
pool.lpToken.safeTransfer(address(msg.sender), _amount);
emit Withdraw(msg.sender, _pid, _amount);
}
// transfer VSTRIKE
function move(uint256 _pid, address _sender, address _recipient, uint256 _vstrikeAmount) override external nonReentrant {
require(vStrk == msg.sender);
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage sender = userInfo[_pid][_sender];
UserInfo storage recipient = userInfo[_pid][_recipient];
uint256 amount = _vstrikeAmount.div(VSTRK_RATE);
require(sender.amount + sender.pendingAmount >= amount, "transfer exceeds amount");
require(block.timestamp - sender.depositedDate > unstakableTime, "not eligible to undtake");
updatePool(_pid);
_claimBaseRewards(_pid, _sender);
if (sender.amount > 0) {
sender.amount = sender.amount.sub(amount);
} else {
sender.pendingAmount = sender.pendingAmount.sub(amount);
}
sender.rewardDebt = sender.amount.mul(pool.accRewardPerShare).div(accMulFactor);
sender.boostedDate = block.timestamp;
// will loose unclaimed boost reward
sender.accBoostReward = 0;
sender.boostRewardDebt = 0;
bool claimEligible = checkRewardClaimEligible(recipient.depositedDate);
bool rewardEligible = checkRewardEligible(recipient.boostFactors.length);
if (claimEligible && rewardEligible) {
_claimBaseRewards(_pid, _recipient);
}
if (rewardEligible) {
recipient.amount = recipient.amount.add(recipient.pendingAmount).add(amount);
recipient.pendingAmount = 0;
} else {
recipient.pendingAmount = recipient.pendingAmount.add(amount);
}
recipient.rewardDebt = recipient.amount.mul(pool.accRewardPerShare).div(accMulFactor);
recipient.boostedDate = block.timestamp;
}
// Withdraw without caring about rewards. EMERGENCY ONLY.
function emergencyWithdraw(uint256 _pid) external nonReentrant {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
pool.lpToken.safeTransfer(address(msg.sender), user.amount.add(user.pendingAmount));
emit EmergencyWithdraw(msg.sender, _pid, user.amount);
if (user.amount > 0) {
pool.rewardEligibleSupply = pool.rewardEligibleSupply.sub(user.amount);
}
user.amount = 0;
user.pendingAmount = 0;
user.rewardDebt = 0;
user.boostRewardDebt = 0;
user.accBoostReward = 0;
}
// Safe rewardToken transfer function, just in case if rounding error causes pool to not have enough STRIKEs.
function safeRewardTransfer(address _to, uint256 _amount) internal {
uint256 availableBal = IERC20(rewardToken).balanceOf(address(this));
// Protect users liquidity
if (strk == rewardToken) {
if (availableBal > lpSupplyOfStrikePool) {
availableBal = availableBal - lpSupplyOfStrikePool;
} else {
availableBal = 0;
}
}
if (_amount > availableBal) {
IERC20(rewardToken).transfer(_to, availableBal);
} else {
IERC20(rewardToken).transfer(_to, _amount);
}
}
function setAccMulFactor(uint256 _factor) external onlyOwner {
accMulFactor = _factor;
}
function updateInitialBoostMultiplier(uint _initialBoostMultiplier) external onlyOwner {
initialBoostMultiplier = _initialBoostMultiplier;
}
function updatedBoostMultiplierFactor(uint _boostMultiplierFactor) external onlyOwner {
boostMultiplierFactor = _boostMultiplierFactor;
}
// Update reward token address by owner.
function updateRewardToken(address _reward) external onlyOwner {
rewardToken = _reward;
}
// Update claimBaseRewardTime
function updateClaimBaseRewardTime(uint256 _claimBaseRewardTime) external onlyOwner {
claimBaseRewardTime = _claimBaseRewardTime;
}
// Update unstakableTime
function updateUnstakableTime(uint256 _unstakableTime) external onlyOwner {
unstakableTime = _unstakableTime;
}
// NFT Boosting
// get boosted users
function getBoostedUserCount(uint256 _pid) external view returns(uint256) {
return boostedUsers[_pid].length;
}
// View function to see pending STRIKEs on frontend.
function pendingBoostReward(uint256 _pid, address _user)
external
view
returns (uint256)
{
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_user];
uint256 accRewardPerShare = pool.accRewardPerShare;
if (block.number > pool.lastRewardBlock && pool.rewardEligibleSupply > 0) {
uint256 multiplier =
getMultiplier(pool.lastRewardBlock, block.number);
uint256 reward =
multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(
totalAllocPoint
);
accRewardPerShare = accRewardPerShare.add(
reward.mul(accMulFactor).div(pool.rewardEligibleSupply)
);
}
uint256 boostMultiplier = getBoostMultiplier(user.boostFactors.length);
uint256 baseReward = user.amount.mul(accRewardPerShare).div(accMulFactor).sub(user.rewardDebt);
uint256 boostReward = boostMultiplier.mul(baseReward).div(100);
return user.accBoostReward.sub(user.boostRewardDebt).add(boostReward);
}
// for deposit reward token to contract
function getTotalPendingBoostRewards() external view returns (uint256) {
uint256 totalRewards;
for (uint i; i < poolInfo.length; i++) {
PoolInfo storage pool = poolInfo[i];
uint256 accRewardPerShare = pool.accRewardPerShare;
for (uint j; j < boostedUsers[i].length; j++) {
UserInfo storage user = userInfo[i][boostedUsers[i][j]];
if (block.number > pool.lastRewardBlock && pool.rewardEligibleSupply > 0) {
uint256 multiplier =
getMultiplier(pool.lastRewardBlock, block.number);
uint256 reward =
multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(
totalAllocPoint
);
accRewardPerShare = accRewardPerShare.add(
reward.mul(accMulFactor).div(pool.rewardEligibleSupply)
);
}
uint256 boostMultiplier = getBoostMultiplier(user.boostFactors.length);
uint256 baseReward = user.amount.mul(accRewardPerShare).div(accMulFactor).sub(user.rewardDebt);
uint256 initBoostReward = boostMultiplier.mul(baseReward).div(100);
uint256 boostReward = user.accBoostReward.sub(user.boostRewardDebt).add(initBoostReward);
totalRewards = totalRewards.add(boostReward);
}
}
return totalRewards;
}
// for deposit reward token to contract
function getClaimablePendingBoostRewards() external view returns (uint256) {
uint256 totalRewards;
for (uint i; i < poolInfo.length; i++) {
PoolInfo storage pool = poolInfo[i];
uint256 accRewardPerShare = pool.accRewardPerShare;
for (uint j; j < boostedUsers[i].length; j++) {
UserInfo storage user = userInfo[i][boostedUsers[i][j]];
if (block.timestamp - user.boostedDate >= claimBoostRewardTime) {
if (block.number > pool.lastRewardBlock && pool.rewardEligibleSupply > 0) {
uint256 multiplier =
getMultiplier(pool.lastRewardBlock, block.number);
uint256 reward =
multiplier.mul(rewardPerBlock).mul(pool.allocPoint).div(
totalAllocPoint
);
accRewardPerShare = accRewardPerShare.add(
reward.mul(accMulFactor).div(pool.rewardEligibleSupply)
);
}
uint256 boostMultiplier = getBoostMultiplier(user.boostFactors.length);
uint256 baseReward = user.amount.mul(accRewardPerShare).div(accMulFactor).sub(user.rewardDebt);
uint256 initBoostReward = boostMultiplier.mul(baseReward).div(100);
uint256 boostReward = user.accBoostReward.sub(user.boostRewardDebt).add(initBoostReward);
totalRewards = totalRewards.add(boostReward);
}
}
}
return totalRewards;
}
// Claim boost reward
function claimBoostReward(uint256 _pid) external {
UserInfo storage user = userInfo[_pid][msg.sender];
require(block.timestamp - user.boostedDate > claimBoostRewardTime, "not eligible to claim");
PoolInfo storage pool = poolInfo[_pid];
updatePool(_pid);
_claimBaseRewards(_pid, msg.sender);
user.rewardDebt = user.amount.mul(pool.accRewardPerShare).div(accMulFactor);
uint256 boostReward = user.accBoostReward.sub(user.boostRewardDebt);
safeRewardTransfer(msg.sender, boostReward);
emit ClaimBoostRewards(msg.sender, _pid, boostReward);
user.boostRewardDebt = user.boostRewardDebt.add(boostReward);
user.boostedDate = block.timestamp;
}
function _boost(uint256 _pid, uint _tokenId) internal {
require (isBoosted[_tokenId] == false, "already boosted");
boostFactor.transferFrom(msg.sender, address(this), _tokenId);
// boostFactor.updateStakeTime(_tokenId, true);
isBoosted[_tokenId] = true;
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
if (user.pendingAmount > 0) {
user.amount = user.pendingAmount;
pool.rewardEligibleSupply = pool.rewardEligibleSupply.add(user.amount);
user.pendingAmount = 0;
}
user.boostFactors.push(_tokenId);
pool.totalBoostCount = pool.totalBoostCount + 1;
emit Boost(msg.sender, _pid, _tokenId);
}
function boost(uint256 _pid, uint _tokenId) external {
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.amount + user.pendingAmount > 0, "no stake tokens");
require(user.boostFactors.length + 1 <= maximumBoostCount);
PoolInfo storage pool = poolInfo[_pid];
if (user.boostFactors.length == 0) {
boostedUsers[_pid].push(msg.sender);
}
updatePool(_pid);
_claimBaseRewards(_pid, msg.sender);
_boost(_pid, _tokenId);
user.rewardDebt = user.amount.mul(pool.accRewardPerShare).div(accMulFactor);
user.boostedDate = block.timestamp;
}
function boostPartially(uint _pid, uint tokenAmount) external {
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.amount + user.pendingAmount > 0, "no stake tokens");
require(user.boostFactors.length + tokenAmount <= maximumBoostCount);
PoolInfo storage pool = poolInfo[_pid];
if (user.boostFactors.length == 0) {
boostedUsers[_pid].push(msg.sender);
}
uint256 ownerTokenCount = boostFactor.balanceOf(msg.sender);
require(tokenAmount <= ownerTokenCount);
updatePool(_pid);
_claimBaseRewards(_pid, msg.sender);
for (uint i; i < tokenAmount; i++) {
uint _tokenId = boostFactor.tokenOfOwnerByIndex(msg.sender, 0);
_boost(_pid, _tokenId);
}
user.rewardDebt = user.amount.mul(pool.accRewardPerShare).div(accMulFactor);
user.boostedDate = block.timestamp;
}
function boostAll(uint _pid, uint256[] memory _tokenIds) external {
uint256 tokenIdLength = _tokenIds.length;
require(tokenIdLength > 0, "");
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.amount + user.pendingAmount > 0, "no stake tokens");
uint256 ownerTokenCount = boostFactor.balanceOf(msg.sender);
require(ownerTokenCount > 0, "");
PoolInfo storage pool = poolInfo[_pid];
if (user.boostFactors.length == 0) {
boostedUsers[_pid].push(msg.sender);
}
uint256 availableTokenAmount = maximumBoostCount - user.boostFactors.length;
require(availableTokenAmount > 0, "overflow maximum boosting");
if (tokenIdLength < availableTokenAmount) {
availableTokenAmount = tokenIdLength;
}
updatePool(_pid);
_claimBaseRewards(_pid, msg.sender);
for (uint256 i; i < availableTokenAmount; i++) {
_boost(_pid, _tokenIds[i]);
}
user.rewardDebt = user.amount.mul(pool.accRewardPerShare).div(accMulFactor);
user.boostedDate = block.timestamp;
}
function _unBoost(uint _pid, uint _tokenId) internal {
require (isBoosted[_tokenId] == true);
boostFactor.transferFrom(address(this), msg.sender, _tokenId);
// boostFactor.updateStakeTime(_tokenId, false);
isBoosted[_tokenId] = false;
emit UnBoost(msg.sender, _pid, _tokenId);
}
function unBoost(uint _pid, uint _tokenId) external {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.boostFactors.length > 0, "");
uint factorLength = user.boostFactors.length;
updatePool(_pid);
_claimBaseRewards(_pid, msg.sender);
bool found = false;
uint dfId; // will be deleted factor index
for (uint j; j < factorLength; j++) {
if (_tokenId == user.boostFactors[j]) {
dfId = j;
found = true;
break;
}
}
require(found, "not found boosted tokenId");
_unBoost(_pid, _tokenId);
user.boostFactors[dfId] = user.boostFactors[factorLength - 1];
user.boostFactors.pop();
pool.totalBoostCount = pool.totalBoostCount - 1;
user.boostedDate = block.timestamp;
// will loose unclaimed boost reward
user.accBoostReward = 0;
user.boostRewardDebt = 0;
uint boostedUserCount = boostedUsers[_pid].length;
if (user.boostFactors.length == 0) {
user.pendingAmount = user.amount;
user.amount = 0;
pool.rewardEligibleSupply = pool.rewardEligibleSupply.sub(user.pendingAmount);
uint index;
for (uint j; j < boostedUserCount; j++) {
if (address(msg.sender) == address(boostedUsers[_pid][j])) {
index = j;
break;
}
}
boostedUsers[_pid][index] = boostedUsers[_pid][boostedUserCount - 1];
boostedUsers[_pid].pop();
}
user.rewardDebt = user.amount.mul(pool.accRewardPerShare).div(accMulFactor);
}
function unBoostPartially(uint _pid, uint tokenAmount) external {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.boostFactors.length > 0, "");
require(tokenAmount <= user.boostFactors.length, "");
uint factorLength = user.boostFactors.length;
updatePool(_pid);
_claimBaseRewards(_pid, msg.sender);
for (uint i = 1; i <= tokenAmount; i++) {
uint index = factorLength - i;
uint _tokenId = user.boostFactors[index];
_unBoost(_pid, _tokenId);
user.boostFactors.pop();
pool.totalBoostCount = pool.totalBoostCount - 1;
}
user.boostedDate = block.timestamp;
// will loose unclaimed boost reward
user.accBoostReward = 0;
user.boostRewardDebt = 0;
uint boostedUserCount = boostedUsers[_pid].length;
if (user.boostFactors.length == 0) {
user.pendingAmount = user.amount;
user.amount = 0;
pool.rewardEligibleSupply = pool.rewardEligibleSupply.sub(user.pendingAmount);
uint index;
for (uint j; j < boostedUserCount; j++) {
if (address(msg.sender) == address(boostedUsers[_pid][j])) {
index = j;
break;
}
}
boostedUsers[_pid][index] = boostedUsers[_pid][boostedUserCount - 1];
boostedUsers[_pid].pop();
}
user.rewardDebt = user.amount.mul(pool.accRewardPerShare).div(accMulFactor);
}
function unBoostAll(uint _pid) external {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
uint factorLength = user.boostFactors.length;
require(factorLength > 0, "");
updatePool(_pid);
_claimBaseRewards(_pid, msg.sender);
for (uint i = 0; i < factorLength; i++) {
uint _tokenId = user.boostFactors[i];
_unBoost(_pid, _tokenId);
}
delete user.boostFactors;
pool.totalBoostCount = pool.totalBoostCount - factorLength;
user.boostedDate = block.timestamp;
// will loose unclaimed boost reward
user.accBoostReward = 0;
user.boostRewardDebt = 0;
uint boostedUserCount = boostedUsers[_pid].length;
if (user.boostFactors.length == 0) {
user.pendingAmount = user.amount;
user.amount = 0;
pool.rewardEligibleSupply = pool.rewardEligibleSupply.sub(user.pendingAmount);
uint index;
for (uint j; j < boostedUserCount; j++) {
if (address(msg.sender) == address(boostedUsers[_pid][j])) {
index = j;
break;
}
}
boostedUsers[_pid][index] = boostedUsers[_pid][boostedUserCount - 1];
boostedUsers[_pid].pop();
}
user.rewardDebt = user.amount.mul(pool.accRewardPerShare).div(accMulFactor);
}
// Update boostFactor address. Can only be called by the owner.
function setBoostFactor(
address _address
) external onlyOwner {
boostFactor = IBoostToken(_address);
}
// Update claimBoostRewardTime
function updateClaimBoostRewardTime(uint256 _claimBoostRewardTime) external onlyOwner {
claimBoostRewardTime = _claimBoostRewardTime;
}
// Update minimum valid boost token count. Can only be called by the owner.
function updateMinimumValidBoostCount(uint16 _count) external onlyOwner {
minimumValidBoostCount = _count;
}
// Update maximum valid boost token count. Can only be called by the owner.
function updateMaximumBoostCount(uint16 _count) external onlyOwner {
maximumBoostCount = _count;
}
}
IERC20.sol 77 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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 `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool);
/**
* @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);
}
Address.sol 141 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.2;
/**
* @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
* ====
*/
function isContract(address account) internal view returns (bool) {
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != accountHash && codehash != 0x0);
}
/**
* @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://diligence.consensys.net/posts/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.5.11/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");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(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 functionCall(target, data, "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");
return _functionCallWithValue(target, data, value, errorMessage);
}
function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
if (success) {
return returndata;
} else {
// 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
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
Ownable.sol 64 lines
// SPDX-License-Identifier: MIT
// Audit on 5-Jan-2021 by Keno and BoringCrypto
// P1 - P3: OK
pragma solidity 0.6.12;
// Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol + Claimable.sol
// Edited by BoringCrypto
// T1 - T4: OK
contract OwnableData {
// V1 - V5: OK
address public owner;
// V1 - V5: OK
address public pendingOwner;
}
// T1 - T4: OK
contract Ownable is OwnableData {
// E1: OK
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () internal {
owner = msg.sender;
emit OwnershipTransferred(address(0), msg.sender);
}
// F1 - F9: OK
// C1 - C21: OK
function transferOwnership(address newOwner, bool direct, bool renounce) public onlyOwner {
if (direct) {
// Checks
require(newOwner != address(0) || renounce, "Ownable: zero address");
// Effects
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
} else {
// Effects
pendingOwner = newOwner;
}
}
// F1 - F9: OK
// C1 - C21: OK
function claimOwnership() public {
address _pendingOwner = pendingOwner;
// Checks
require(msg.sender == _pendingOwner, "Ownable: caller != pending owner");
// Effects
emit OwnershipTransferred(owner, _pendingOwner);
owner = _pendingOwner;
pendingOwner = address(0);
}
// M1 - M5: OK
// C1 - C21: OK
modifier onlyOwner() {
require(msg.sender == owner, "Ownable: caller is not the owner");
_;
}
}
IERC165.sol 24 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.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);
}
IERC721.sol 129 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.2;
import "./IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transfered from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 tokenId) external;
/**
* @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 Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @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 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);
/**
* @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;
}
SafeMath.sol 159 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
IVStrike.sol 20 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IVStrike {
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Mint} event.
*/
function mint(address recipient, uint256 amount) external returns (bool);
function burnFrom(address account, uint256 amount) external;
}
SafeERC20.sol 75 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "../interfaces/IERC20.sol";
import "../libraries/SafeMath.sol";
import "../libraries/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 SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
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'
// solhint-disable-next-line max-line-length
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));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @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");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
IBoostToken.sol 11 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.2;
import "./IERC721Enumerable.sol";
interface IBoostToken is IERC721Enumerable {
function updateStakeTime(uint tokenId, bool isStake) external;
function getTokenOwner(uint tokenId) external view returns(address);
}
EnumerableSet.sol 243 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.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.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.0.0, only sets of type `address` (`AddressSet`) and `uint256`
* (`UintSet`) are supported.
*/
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;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
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] = toDeleteIndex + 1; // All indexes are 1-based
// 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) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
// 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(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(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(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(uint256(_at(set._inner, index)));
}
// 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 on 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));
}
}
ReentrancyGuard.sol 61 lines
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor () internal {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
IERC721Receiver.sol 22 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
*/
function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data)
external returns (bytes4);
}
IStrikeBoostFarm.sol 10 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IStrikeBoostFarm {
function move(uint256 pid, address sender, address recipient, uint256 amount) external;
}
IERC721Enumerable.sol 29 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.2;
import "./IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Enumerable is IERC721 {
/**
* @dev Returns the total amount of tokens stored by the contract.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns a token ID owned by `owner` at a given `index` of its token list.
* Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);
/**
* @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
* Use along with {totalSupply} to enumerate all tokens.
*/
function tokenByIndex(uint256 index) external view returns (uint256);
}
Read Contract
BONUS_MULTIPLIER 0x8aa28550 → uint256
VSTRK_RATE 0x09cfb6b9 → uint256
bonusEndBlock 0x1aed6553 → uint256
boostFactor 0xc1ddfb00 → address
boostMultiplierFactor 0x9b80d281 → uint256
claimBaseRewardTime 0xbd48cf22 → uint256
claimBoostRewardTime 0x11aedfbc → uint256
getBoostedUserCount 0xb5bda70d → uint256
getClaimablePendingBoostRewards 0xc0db8887 → uint256
getMultiplier 0x8dbb1e3a → uint256
getPoolInfo 0x2f380b35 → address, uint256, uint256, uint256, uint256, uint256, uint256
getTotalPendingBoostRewards 0xc0bccbfb → uint256
getUserInfo 0x1069f3b5 → uint256, uint256, uint256, uint256, uint256[], uint256, uint256, uint256, uint256
initialBoostMultiplier 0xe0e2f310 → uint256
isBoosted 0x21ab46c8 → bool
maximumBoostCount 0x648b8c6b → uint16
minimumValidBoostCount 0xf6d4c185 → uint16
owner 0x8da5cb5b → address
pendingBaseReward 0xbcabf89b → uint256
pendingBoostReward 0x73cb07d8 → uint256
pendingOwner 0xe30c3978 → address
pendingReward 0x98969e82 → uint256
poolLength 0x081e3eda → uint256
rewardPerBlock 0x8ae39cac → uint256
rewardToken 0xf7c618c1 → address
startBlock 0x48cd4cb1 → uint256
strk 0xf24e5343 → address
totalAllocPoint 0x17caf6f1 → uint256
unstakableTime 0xda38f3af → uint256
userInfo 0x93f1a40b → uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256
vStrk 0xfecedb65 → address
Write Contract 29 functions
These functions modify contract state and require a wallet transaction to execute.
add 0x1eaaa045
uint256 _allocPoint
address _lpToken
bool _withUpdate
boost 0x40be7bec
uint256 _pid
uint256 _tokenId
boostAll 0x6e2cba99
uint256 _pid
uint256[] _tokenIds
boostPartially 0x11ea3264
uint256 _pid
uint256 tokenAmount
claimBaseRewards 0xe78c1b1b
uint256 _pid
claimBoostReward 0x42a9026a
uint256 _pid
claimOwnership 0x4e71e0c8
No parameters
deposit 0xe2bbb158
uint256 _pid
uint256 _amount
emergencyWithdraw 0x5312ea8e
uint256 _pid
massUpdatePools 0x630b5ba1
No parameters
move 0x52e0371c
uint256 _pid
address _sender
address _recipient
uint256 _vstrikeAmount
set 0x64482f79
uint256 _pid
uint256 _allocPoint
bool _withUpdate
setAccMulFactor 0xf54ac4c1
uint256 _factor
setBoostFactor 0x488a8f58
address _address
setRewardPerBlock 0xbb872b4a
uint256 speed
transferOwnership 0x078dfbe7
address newOwner
bool direct
bool renounce
unBoost 0x0fc035df
uint256 _pid
uint256 _tokenId
unBoostAll 0xd94f11be
uint256 _pid
unBoostPartially 0x0fa6b3a0
uint256 _pid
uint256 tokenAmount
updateClaimBaseRewardTime 0x766d7cfb
uint256 _claimBaseRewardTime
updateClaimBoostRewardTime 0x4638cef5
uint256 _claimBoostRewardTime
updateInitialBoostMultiplier 0xd895745c
uint256 _initialBoostMultiplier
updateMaximumBoostCount 0x69914d62
uint16 _count
updateMinimumValidBoostCount 0x1a249f5c
uint16 _count
updatePool 0x51eb05a6
uint256 _pid
updateRewardToken 0xf8cf31cb
address _reward
updateUnstakableTime 0xd8fd5a7a
uint256 _unstakableTime
updatedBoostMultiplierFactor 0xd5f9464e
uint256 _boostMultiplierFactor
withdraw 0x441a3e70
uint256 _pid
uint256 _amount
Recent Transactions
No transactions found for this address