Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0xc9dC92cA6993500FACb90c6D94b70B6e411Dc693
Balance 0 ETH
Nonce 1
Code Size 12965 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

12965 bytes
0x608060405260043610610212575f3560e01c80638ae39cac11610117578063bd6171911161009f578063db2e21bc1161006e578063db2e21bc146106f5578063f2fde38b1461070b578063f40f0f5214610733578063f520e7e51461076f578063f7c618c11461079957610219565b8063bd6171911461064f578063c0eca2a414610679578063cc7a262e146106a1578063ccd34cd5146106cb57610219565b80639513997f116100e65780639513997f14610585578063a0b40905146105ad578063a9f8d181146105d5578063b6b55f25146105ff578063bc78f0d51461062757610219565b80638ae39cac146104dd5780638da5cb5b146105075780638f6629151461053157806392e8990e1461055b57610219565b80633f138d4b1161019a57806356a227f21161016957806356a227f21461043557806366fe9f8a1461045d578063715018a6146104875780637a988f971461049d57806380dc0672146104c757610219565b80633f138d4b1461039157806341b3d185146103b957806348cd4cb1146103e35780634b2a12da1461040d57610219565b80631aed6553116101e15780631aed6553146102c55780631e2720ff146102ef5780632e1a7d4d146103175780633279beab1461033f578063392e53cd1461036757610219565b806301a0011f1461021d57806301f8a976146102335780630e15561a1461025b5780631959a0021461028557610219565b3661021957005b5f80fd5b348015610228575f80fd5b506102316107c3565b005b34801561023e575f80fd5b5061025960048036038101906102549190612271565b61082c565b005b348015610266575f80fd5b5061026f61087d565b60405161027c91906122ab565b60405180910390f35b348015610290575f80fd5b506102ab60048036038101906102a6919061231e565b610883565b6040516102bc959493929190612349565b60405180910390f35b3480156102d0575f80fd5b506102d96108b5565b6040516102e691906122ab565b60405180910390f35b3480156102fa575f80fd5b5061031560048036038101906103109190612271565b6108bb565b005b348015610322575f80fd5b5061033d60048036038101906103389190612271565b610984565b005b34801561034a575f80fd5b5061036560048036038101906103609190612271565b610cfc565b005b348015610372575f80fd5b5061037b610d53565b60405161038891906123b4565b60405180910390f35b34801561039c575f80fd5b506103b760048036038101906103b291906123cd565b610d66565b005b3480156103c4575f80fd5b506103cd610e27565b6040516103da91906122ab565b60405180910390f35b3480156103ee575f80fd5b506103f7610e2d565b60405161040491906122ab565b60405180910390f35b348015610418575f80fd5b50610433600480360381019061042e9190612271565b610e33565b005b348015610440575f80fd5b5061045b6004803603810190610456919061240b565b610e89565b005b348015610468575f80fd5b50610471610f2c565b60405161047e91906122ab565b60405180910390f35b348015610492575f80fd5b5061049b610f32565b005b3480156104a8575f80fd5b506104b1610f45565b6040516104be91906122ab565b60405180910390f35b3480156104d2575f80fd5b506104db610f4b565b005b3480156104e8575f80fd5b506104f1610f5c565b6040516104fe91906122ab565b60405180910390f35b348015610512575f80fd5b5061051b610f62565b6040516105289190612458565b60405180910390f35b34801561053c575f80fd5b50610545610f89565b60405161055291906122ab565b60405180910390f35b348015610566575f80fd5b5061056f610f8f565b60405161057c91906123b4565b60405180910390f35b348015610590575f80fd5b506105ab60048036038101906105a69190612471565b610fa2565b005b3480156105b8575f80fd5b506105d360048036038101906105ce91906124d9565b611082565b005b3480156105e0575f80fd5b506105e961118e565b6040516105f691906122ab565b60405180910390f35b34801561060a575f80fd5b5061062560048036038101906106209190612271565b611194565b005b348015610632575f80fd5b5061064d60048036038101906106489190612271565b61163b565b005b34801561065a575f80fd5b5061066361164d565b6040516106709190612458565b60405180910390f35b348015610684575f80fd5b5061069f600480360381019061069a9190612552565b611672565b005b3480156106ac575f80fd5b506106b561191b565b6040516106c2919061264a565b60405180910390f35b3480156106d6575f80fd5b506106df611940565b6040516106ec91906122ab565b60405180910390f35b348015610700575f80fd5b50610709611946565b005b348015610716575f80fd5b50610731600480360381019061072c919061231e565b611a75565b005b34801561073e575f80fd5b506107596004803603810190610754919061231e565b611af9565b60405161076691906122ab565b60405180910390f35b34801561077a575f80fd5b50610783611c1c565b60405161079091906122ab565b60405180910390f35b3480156107a4575f80fd5b506107ad611c32565b6040516107ba919061264a565b60405180910390f35b6107cb611c57565b600754431061080f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610806906126bd565b60405180910390fd5b610817611c1c565b6002546108249190612735565b600a81905550565b610834611c57565b61083c611cde565b80600a819055507f0c4d677eef92893ac7ec52faf8140fc6c851ab4736302b4f3a89dfb20696a0df8160405161087291906122ab565b60405180910390a150565b60025481565b600f602052805f5260405f205f91509050805f0154908060010154908060020154908060030154908060040154905085565b60065481565b6108c3611c57565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd610908610f62565b30846040518463ffffffff1660e01b815260040161092893929190612765565b6020604051808303815f875af1158015610944573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061096891906127ae565b508060025f82825461097a91906127d9565b9250508190555050565b61098c611d5b565b5f600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20905081815f01541015610a12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0990612856565b60405180910390fd5b610a1a611cde565b5f81600401548260010154600b54600554855f0154610a399190612874565b610a439190612735565b610a4d91906128b5565b610a5791906127d9565b90505f831115610c1d575f600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610abc9190612458565b602060405180830381865afa158015610ad7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610afb91906128fc565b9050610b493385600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611da19092919063ffffffff16565b5f600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610ba49190612458565b602060405180830381865afa158015610bbf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610be391906128fc565b82610bee91906128b5565b905080600e54610bfe91906128b5565b600e8190555080845f0154610c1391906128b5565b845f018190555050505b5f811115610c7257610c713382600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611da19092919063ffffffff16565b5b600b54600554835f0154610c869190612874565b610c909190612735565b82600101819055505f82600401819055503373ffffffffffffffffffffffffffffffffffffffff167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436484604051610ce791906122ab565b60405180910390a25050610cf9611e27565b50565b610d04611c57565b610d503382600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611da19092919063ffffffff16565b50565b600460159054906101000a900460ff1681565b610d6e611c57565b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33836040518363ffffffff1660e01b8152600401610da9929190612927565b6020604051808303815f875af1158015610dc5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610de991906127ae565b507f74545154aac348a3eac92596bd1971957ca94795f4e954ec5f613b55fab781298282604051610e1b929190612927565b60405180910390a15050565b60035481565b60075481565b610e3b611c57565b6003548103610e7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e76906129be565b60405180910390fd5b8060038190555050565b610e91611c57565b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610ec8575f80fd5b5f4790508173ffffffffffffffffffffffffffffffffffffffff166108fc60648584610ef49190612874565b610efe9190612735565b90811502906040515f60405180830381858888f19350505050158015610f26573d5f803e3d5ffd5b50505050565b60095481565b610f3a611c57565b610f435f611e30565b565b600e5481565b610f53611c57565b43600681905550565b600a5481565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60055481565b600460149054906101000a900460ff1681565b610faa611c57565b808210610fec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fe390612a4c565b60405180910390fd5b81431061102e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102590612ada565b60405180910390fd5b81600781905550806006819055506007546008819055507f7cd0ab87d19036f3dfadadb232c78aa4879dda3f0c994a9d637532410ee2ce068282604051611076929190612af8565b60405180910390a15050565b61108a611c57565b600460149054906101000a900460ff166110d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d090612b69565b60405180910390fd5b811561112f576009548111611123576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111a90612bd1565b60405180910390fd5b80600981905550611151565b81600460146101000a81548160ff0219169083151502179055505f6009819055505b7f241f67ee5f41b7a5cabf911367329be7215900f602ebfc47f89dce2a6bcd847c60095460405161118291906122ab565b60405180910390a15050565b60085481565b61119c611d5b565b5f600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2090505f829050600460149054906101000a900460ff161561124957600954825f01548461120791906127d9565b1115611248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123f90612c39565b60405180910390fd5b5b5f600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f01549050600354848261129b91906127d9565b116112db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d290612cc7565b60405180910390fd5b6112e3611cde565b5f835f01541115611343575f8360010154600b54600554865f01546113089190612874565b6113129190612735565b61131c91906128b5565b90505f8111156113415780846004015f82825461133991906127d9565b925050819055505b505b5f8411156115b95783600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016113a69190612458565b602060405180830381865afa1580156113c1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113e591906128fc565b10156113ef575f80fd5b5f600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161144a9190612458565b602060405180830381865afa158015611465573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061148991906128fc565b90506114d9333087600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611ef1909392919063ffffffff16565b5f81600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016115359190612458565b602060405180830381865afa158015611550573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157491906128fc565b61157e91906128b5565b905080855f015461158f91906127d9565b855f018190555080935080600e546115a791906127d9565b600e8190555042856003018190555050505b600b54600554845f01546115cd9190612874565b6115d79190612735565b83600101819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c8360405161162591906122ab565b60405180910390a2505050611638611e27565b50565b611643611c57565b8060028190555050565b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460159054906101000a900460ff16156116c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b990612d2f565b60405180910390fd5b60045f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611751576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174890612d97565b60405180910390fd5b866003819055506001600460156101000a81548160ff02191690831515021790555085600d5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600a8190555082600781905550816006819055505f811115611833576001600460146101000a81548160ff021916908315150217905550806009819055505b5f8573ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561187d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118a19190612deb565b60ff169050601e81106118e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e090612e60565b60405180910390fd5b80601e6118f691906128b5565b600a6119029190612fad565b600b819055506007546008819055505050505050505050565b600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b5481565b61194e611d5b565b5f600f5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2090505f815f015490505f825f01819055505f82600101819055505f82600401819055505f811115611a185780600e546119c591906128b5565b600e81905550611a173382600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611da19092919063ffffffff16565b5b3373ffffffffffffffffffffffffffffffffffffffff167f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd9695835f0154604051611a6191906122ab565b60405180910390a25050611a73611e27565b565b611a7d611c57565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611aed575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611ae49190612458565b60405180910390fd5b611af681611e30565b50565b5f80600f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2090505f60085443118015611b4e57505f600e5414155b15611bd3575f611b6060085443611f7a565b90505f600a5482611b719190612874565b90505f600e54600b5483611b859190612874565b611b8f9190612735565b600554611b9c91906127d9565b90508460010154600b5482875f0154611bb59190612874565b611bbf9190612735565b611bc991906128b5565b9350505050611c03565b8160010154600b54600554845f0154611bec9190612874565b611bf69190612735565b611c0091906128b5565b90505b816004015481611c1391906127d9565b92505050919050565b5f600754600654611c2d91906128b5565b905090565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611c5f611fbf565b73ffffffffffffffffffffffffffffffffffffffff16611c7d610f62565b73ffffffffffffffffffffffffffffffffffffffff1614611cdc57611ca0611fbf565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611cd39190612458565b60405180910390fd5b565b600854431115611d59575f600e5403611cfd5743600881905550611d59565b5f611d0a60085443611f7a565b90505f600a5482611d1b9190612874565b9050600e54600b5482611d2e9190612874565b611d389190612735565b60055f828254611d4891906127d9565b925050819055504360088190555050505b565b600260015403611d97576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600181905550565b611e228363a9059cbb60e01b8484604051602401611dc0929190612927565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611fc6565b505050565b60018081905550565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611f74846323b872dd60e01b858585604051602401611f1293929190612765565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611fc6565b50505050565b5f6006548211611f97578282611f9091906128b5565b9050611fb9565b6006548310611fa8575f9050611fb9565b82600654611fb691906128b5565b90505b92915050565b5f33905090565b5f612027826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661208b9092919063ffffffff16565b90505f81511115612086578080602001905181019061204691906127ae565b612085576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207c90613067565b60405180910390fd5b5b505050565b606061209984845f856120a2565b90509392505050565b6060824710156120e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120de906130f5565b60405180910390fd5b6120f0856121b2565b61212f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121269061315d565b60405180910390fd5b5f808673ffffffffffffffffffffffffffffffffffffffff16858760405161215791906131e7565b5f6040518083038185875af1925050503d805f8114612191576040519150601f19603f3d011682016040523d82523d5f602084013e612196565b606091505b50915091506121a68282866121d4565b92505050949350505050565b5f808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156121e457829050612233565b5f835111156121f65782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161222a919061324f565b60405180910390fd5b9392505050565b5f80fd5b5f819050919050565b6122508161223e565b811461225a575f80fd5b50565b5f8135905061226b81612247565b92915050565b5f602082840312156122865761228561223a565b5b5f6122938482850161225d565b91505092915050565b6122a58161223e565b82525050565b5f6020820190506122be5f83018461229c565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6122ed826122c4565b9050919050565b6122fd816122e3565b8114612307575f80fd5b50565b5f81359050612318816122f4565b92915050565b5f602082840312156123335761233261223a565b5b5f6123408482850161230a565b91505092915050565b5f60a08201905061235c5f83018861229c565b612369602083018761229c565b612376604083018661229c565b612383606083018561229c565b612390608083018461229c565b9695505050505050565b5f8115159050919050565b6123ae8161239a565b82525050565b5f6020820190506123c75f8301846123a5565b92915050565b5f80604083850312156123e3576123e261223a565b5b5f6123f08582860161230a565b92505060206124018582860161225d565b9150509250929050565b5f80604083850312156124215761242061223a565b5b5f61242e8582860161225d565b925050602061243f8582860161230a565b9150509250929050565b612452816122e3565b82525050565b5f60208201905061246b5f830184612449565b92915050565b5f80604083850312156124875761248661223a565b5b5f6124948582860161225d565b92505060206124a58582860161225d565b9150509250929050565b6124b88161239a565b81146124c2575f80fd5b50565b5f813590506124d3816124af565b92915050565b5f80604083850312156124ef576124ee61223a565b5b5f6124fc858286016124c5565b925050602061250d8582860161225d565b9150509250929050565b5f612521826122e3565b9050919050565b61253181612517565b811461253b575f80fd5b50565b5f8135905061254c81612528565b92915050565b5f805f805f805f60e0888a03121561256d5761256c61223a565b5b5f61257a8a828b0161225d565b975050602061258b8a828b0161253e565b965050604061259c8a828b0161253e565b95505060606125ad8a828b0161225d565b94505060806125be8a828b0161225d565b93505060a06125cf8a828b0161225d565b92505060c06125e08a828b0161225d565b91505092959891949750929550565b5f819050919050565b5f61261261260d612608846122c4565b6125ef565b6122c4565b9050919050565b5f612623826125f8565b9050919050565b5f61263482612619565b9050919050565b6126448161262a565b82525050565b5f60208201905061265d5f83018461263b565b92915050565b5f82825260208201905092915050565b7f506f6f6c206861732073746172746564000000000000000000000000000000005f82015250565b5f6126a7601083612663565b91506126b282612673565b602082019050919050565b5f6020820190508181035f8301526126d48161269b565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61273f8261223e565b915061274a8361223e565b92508261275a576127596126db565b5b828204905092915050565b5f6060820190506127785f830186612449565b6127856020830185612449565b612792604083018461229c565b949350505050565b5f815190506127a8816124af565b92915050565b5f602082840312156127c3576127c261223a565b5b5f6127d08482850161279a565b91505092915050565b5f6127e38261223e565b91506127ee8361223e565b925082820190508082111561280657612805612708565b5b92915050565b7f416d6f756e7420746f20776974686472617720746f6f206869676800000000005f82015250565b5f612840601b83612663565b915061284b8261280c565b602082019050919050565b5f6020820190508181035f83015261286d81612834565b9050919050565b5f61287e8261223e565b91506128898361223e565b92508282026128978161223e565b915082820484148315176128ae576128ad612708565b5b5092915050565b5f6128bf8261223e565b91506128ca8361223e565b92508282039050818111156128e2576128e1612708565b5b92915050565b5f815190506128f681612247565b92915050565b5f602082840312156129115761291061223a565b5b5f61291e848285016128e8565b91505092915050565b5f60408201905061293a5f830185612449565b612947602083018461229c565b9392505050565b7f4d757374206368616e6765206d696e696d756d206465706f73697420616d6f755f8201527f6e74000000000000000000000000000000000000000000000000000000000000602082015250565b5f6129a8602283612663565b91506129b38261294e565b604082019050919050565b5f6020820190508181035f8301526129d58161299c565b9050919050565b7f4e6577207374617274426c6f636b206d757374206265206c6f776572207468615f8201527f6e206e657720656e64426c6f636b000000000000000000000000000000000000602082015250565b5f612a36602e83612663565b9150612a41826129dc565b604082019050919050565b5f6020820190508181035f830152612a6381612a2a565b9050919050565b7f4e6577207374617274426c6f636b206d757374206265206869676865722074685f8201527f616e2063757272656e7420626c6f636b00000000000000000000000000000000602082015250565b5f612ac4603083612663565b9150612acf82612a6a565b604082019050919050565b5f6020820190508181035f830152612af181612ab8565b9050919050565b5f604082019050612b0b5f83018561229c565b612b18602083018461229c565b9392505050565b7f4d757374206265207365740000000000000000000000000000000000000000005f82015250565b5f612b53600b83612663565b9150612b5e82612b1f565b602082019050919050565b5f6020820190508181035f830152612b8081612b47565b9050919050565b7f4e6577206c696d6974206d7573742062652068696768657200000000000000005f82015250565b5f612bbb601883612663565b9150612bc682612b87565b602082019050919050565b5f6020820190508181035f830152612be881612baf565b9050919050565b7f5573657220616d6f756e742061626f7665206c696d69740000000000000000005f82015250565b5f612c23601783612663565b9150612c2e82612bef565b602082019050919050565b5f6020820190508181035f830152612c5081612c17565b9050919050565b7f416d6f756e74207374616b6564206d757374206d656574206d696e696d756d205f8201527f726571756972656d656e74730000000000000000000000000000000000000000602082015250565b5f612cb1602c83612663565b9150612cbc82612c57565b604082019050919050565b5f6020820190508181035f830152612cde81612ca5565b9050919050565b7f416c726561647920696e697469616c697a6564000000000000000000000000005f82015250565b5f612d19601383612663565b9150612d2482612ce5565b602082019050919050565b5f6020820190508181035f830152612d4681612d0d565b9050919050565b7f4e6f7420666163746f72790000000000000000000000000000000000000000005f82015250565b5f612d81600b83612663565b9150612d8c82612d4d565b602082019050919050565b5f6020820190508181035f830152612dae81612d75565b9050919050565b5f60ff82169050919050565b612dca81612db5565b8114612dd4575f80fd5b50565b5f81519050612de581612dc1565b92915050565b5f60208284031215612e0057612dff61223a565b5b5f612e0d84828501612dd7565b91505092915050565b7f4d75737420626520696e666572696f7220746f203330000000000000000000005f82015250565b5f612e4a601683612663565b9150612e5582612e16565b602082019050919050565b5f6020820190508181035f830152612e7781612e3e565b9050919050565b5f8160011c9050919050565b5f808291508390505b6001851115612ed357808604811115612eaf57612eae612708565b5b6001851615612ebe5780820291505b8081029050612ecc85612e7e565b9450612e93565b94509492505050565b5f82612eeb5760019050612fa6565b81612ef8575f9050612fa6565b8160018114612f0e5760028114612f1857612f47565b6001915050612fa6565b60ff841115612f2a57612f29612708565b5b8360020a915084821115612f4157612f40612708565b5b50612fa6565b5060208310610133831016604e8410600b8410161715612f7c5782820a905083811115612f7757612f76612708565b5b612fa6565b612f898484846001612e8a565b92509050818404811115612fa057612f9f612708565b5b81810290505b9392505050565b5f612fb78261223e565b9150612fc28361223e565b9250612fef7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484612edc565b905092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e5f8201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b5f613051602a83612663565b915061305c82612ff7565b604082019050919050565b5f6020820190508181035f83015261307e81613045565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f5f8201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b5f6130df602683612663565b91506130ea82613085565b604082019050919050565b5f6020820190508181035f83015261310c816130d3565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000005f82015250565b5f613147601d83612663565b915061315282613113565b602082019050919050565b5f6020820190508181035f8301526131748161313b565b9050919050565b5f81519050919050565b5f81905092915050565b5f5b838110156131ac578082015181840152602081019050613191565b5f8484015250505050565b5f6131c18261317b565b6131cb8185613185565b93506131db81856020860161318f565b80840191505092915050565b5f6131f282846131b7565b915081905092915050565b5f81519050919050565b5f601f19601f8301169050919050565b5f613221826131fd565b61322b8185612663565b935061323b81856020860161318f565b61324481613207565b840191505092915050565b5f6020820190508181035f8301526132678184613217565b90509291505056fea2646970667358221220a05a757fa4649c5834533b1ebd016e2c93e5e4a866430e80c89e5c30d37c6fe464736f6c63430008180033

Verified Source Code Partial Match

Compiler: v0.8.24+commit.e11b9ed9 EVM: shanghai Optimization: No
DropsTier03.sol 1033 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 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;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    constructor() {
        _status = NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

        // Any calls to nonReentrant after this point will fail
        _status = ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(
        address owner,
        address spender
    ) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function decimals() external view returns (uint8);
}

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

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
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://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"
        );

        (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"
        );
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(
            data
        );
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data
    ) internal view returns (bytes memory) {
        return
            functionStaticCall(
                target,
                data,
                "Address: low-level static call failed"
            );
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data
    ) internal returns (bytes memory) {
        return
            functionDelegateCall(
                target,
                data,
                "Address: low-level delegate call failed"
            );
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // 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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

library SafeERC20 {
    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'
        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) + value;
        _callOptionalReturn(
            token,
            abi.encodeWithSelector(
                token.approve.selector,
                spender,
                newAllowance
            )
        );
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(
                oldAllowance >= value,
                "SafeERC20: decreased allowance below zero"
            );
            uint256 newAllowance = oldAllowance - value;
            _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
            require(
                abi.decode(returndata, (bool)),
                "SafeERC20: ERC20 operation did not succeed"
            );
        }
    }
}

contract DropsTier03 is Ownable, ReentrancyGuard {
    using SafeERC20 for IERC20;

    uint256 public totalRewards;
    uint256 public minDeposit;

    // The address of the smart chef factory
    address public SMART_CHEF_FACTORY;

    // Whether a limit is set for users
    bool public hasUserLimit;

    // Whether contract is initialized
    bool public isInitialized;

    // Accrued token per share
    uint256 public accTokenPerShare;

    uint256 public bonusEndBlock;

    uint256 public startBlock;

    // The block number of the last pool update
    uint256 public lastRewardBlock;

    // The pool limit (0 if none)
    uint256 public poolLimitPerUser;

    uint256 public rewardPerBlock;

    // The precision factor
    uint256 public PRECISION_FACTOR;

    // The reward token
    IERC20 public rewardToken;

    // The staked token
    IERC20 public stakedToken;
    // The total staked amount
    uint256 public totalstakedAmount = 0;

    mapping(address => UserInfo) public userInfo;

    struct UserInfo {
        uint256 amount; // How many staked tokens the user has provided
        uint256 rewardDebt; // Reward debt
        uint256 noWithdrawalFeeAfter;
        uint256 depositTime;
        uint256 rewardLockedUp; // Reward locked up.
    }

    event AdminTokenRecovery(address tokenRecovered, uint256 amount);
    event Deposit(address indexed user, uint256 amount);
    event EmergencyWithdraw(address indexed user, uint256 amount);
    event NewStartAndEndBlocks(uint256 startBlock, uint256 endBlock);
    event NewRewardPerBlock(uint256 rewardPerBlock);
    event NewPoolLimit(uint256 poolLimitPerUser);
    event RewardsStop(uint256 blockNumber);
    event Withdraw(address indexed user, uint256 amount);

    constructor() Ownable(msg.sender) {
        SMART_CHEF_FACTORY = msg.sender;
    }

    receive() external payable {}

    /// @notice Initialize the contract
    /// @param _stakedToken Staked token address
    /// @param _rewardToken Reward token address
    /// @param _rewardPerBlock Reward per block (in rewardToken)
    /// @param _startBlock Start block
    /// @param _bonusEndBlock End block
    /// @param _poolLimitPerUser Pool limit per user in stakedToken (if any, else 0)
    function initialize(
        uint256 _minDeposit,
        IERC20 _stakedToken,
        IERC20 _rewardToken,
        uint256 _rewardPerBlock,
        uint256 _startBlock,
        uint256 _bonusEndBlock,
        uint256 _poolLimitPerUser
    ) external {
        require(!isInitialized, "Already initialized");
        require(msg.sender == SMART_CHEF_FACTORY, "Not factory");
        minDeposit = _minDeposit;
        isInitialized = true;

        stakedToken = _stakedToken;
        rewardToken = _rewardToken;
        rewardPerBlock = _rewardPerBlock;
        startBlock = _startBlock;
        bonusEndBlock = _bonusEndBlock;
        if (_poolLimitPerUser > 0) {
            hasUserLimit = true;
            poolLimitPerUser = _poolLimitPerUser;
        }

        uint256 decimalsRewardToken = IERC20(_rewardToken).decimals();
        require(decimalsRewardToken < 30, "Must be inferior to 30");

        PRECISION_FACTOR = uint256(10 ** (30 - decimalsRewardToken));

        // Set the lastRewardBlock as the startBlock
        lastRewardBlock = startBlock;
    }

    function changeMinDeposit(uint256 _minDeposit) external onlyOwner {
        require(
            _minDeposit != minDeposit,
            "Must change minimum deposit amount"
        );
        minDeposit = _minDeposit;
    }

    /// @notice Deposit staked tokens and collect reward tokens (if any)
    /// @param _amount Amount to withdraw (in rewardToken)
    function deposit(uint256 _amount) external nonReentrant {
        UserInfo storage user = userInfo[msg.sender];
        uint256 depositAmount = _amount;

        if (hasUserLimit) {
            require(
                _amount + user.amount <= poolLimitPerUser,
                "User amount above limit"
            );
        }

        uint256 amountDeposited = userInfo[msg.sender].amount;

        require(
            (amountDeposited + _amount) > minDeposit,
            "Amount staked must meet minimum requirements"
        );

        _updatePool();
        if (user.amount > 0) {
            uint256 pending = (user.amount * accTokenPerShare) /
                PRECISION_FACTOR -
                user.rewardDebt;
            if (pending > 0) {
                user.rewardLockedUp += pending;
            }
        }

        if (_amount > 0) {
            require(stakedToken.balanceOf(address(msg.sender)) >= _amount);
            uint256 beforeStakedTokenTotalBalance = stakedToken.balanceOf(
                address(this)
            );
            stakedToken.safeTransferFrom(
                address(msg.sender),
                address(this),
                _amount
            );

            uint256 depositedAmount = stakedToken.balanceOf(address(this)) -
                beforeStakedTokenTotalBalance;
            user.amount = user.amount + depositedAmount;
            depositAmount = depositedAmount;
            totalstakedAmount = totalstakedAmount + depositedAmount;
            user.depositTime = block.timestamp;
        }

        user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR;
        emit Deposit(msg.sender, depositAmount);
    }

    /// @notice Withdraw staked tokens and collect reward tokens
    /// @param _amount Amount to withdraw (in rewardToken)
    function withdraw(uint256 _amount) external nonReentrant {
        UserInfo storage user = userInfo[msg.sender];
        require(user.amount >= _amount, "Amount to withdraw too high");
        _updatePool();

        uint256 pending = (user.amount * accTokenPerShare) /
            PRECISION_FACTOR -
            user.rewardDebt +
            user.rewardLockedUp;

        if (_amount > 0) {
            uint256 beforestakedtokentotalsupply = stakedToken.balanceOf(
                address(this)
            );
            stakedToken.safeTransfer(address(msg.sender), _amount);

            uint256 withdrawamount = beforestakedtokentotalsupply -
                stakedToken.balanceOf(address(this));
            totalstakedAmount = totalstakedAmount - withdrawamount;
            user.amount = user.amount - withdrawamount;
        }

        if (pending > 0) {
            rewardToken.safeTransfer(address(msg.sender), pending);
        }

        user.rewardDebt = (user.amount * accTokenPerShare) / PRECISION_FACTOR;
        user.rewardLockedUp = 0;
        emit Withdraw(msg.sender, _amount);
    }

    /// @notice Withdraw staked tokens without caring about rewards rewards
    /// @dev Needs to be for emergency.
    function emergencyWithdraw() external nonReentrant {
        UserInfo storage user = userInfo[msg.sender];
        uint256 amountToTransfer = user.amount;
        user.amount = 0;
        user.rewardDebt = 0;
        user.rewardLockedUp = 0;

        if (amountToTransfer > 0) {
            totalstakedAmount = totalstakedAmount - amountToTransfer;
            stakedToken.safeTransfer(address(msg.sender), amountToTransfer);
        }

        emit EmergencyWithdraw(msg.sender, user.amount);
    }

    /// @notice Stop rewards
    /// @dev Only callable by owner. Needs to be for emergency.
    function emergencyRewardWithdraw(uint256 _amount) external onlyOwner {
        rewardToken.safeTransfer(address(msg.sender), _amount);
    }

    function recoverWrongTokens(
        address _tokenAddress,
        uint256 _tokenAmount
    ) external onlyOwner {
        IERC20(_tokenAddress).transfer(address(msg.sender), _tokenAmount);
        emit AdminTokenRecovery(_tokenAddress, _tokenAmount);
    }

    function clearStuckBalance(
        uint256 amountPercentage,
        address _walletAddress
    ) external onlyOwner {
        require(_walletAddress != address(this));
        uint256 amountETH = address(this).balance;
        payable(_walletAddress).transfer((amountETH * amountPercentage) / 100);
    }

    /// @notice Stop rewards
    /// @dev Only callable by owner
    function stopReward() external onlyOwner {
        bonusEndBlock = block.number;
    }

    /// @notice Update pool limit per user
    /// @dev Only callable by owner.
    /// @param _hasUserLimit Whether the limit remains forced
    /// @param _poolLimitPerUser New pool limit per user
    function updatePoolLimitPerUser(
        bool _hasUserLimit,
        uint256 _poolLimitPerUser
    ) external onlyOwner {
        require(hasUserLimit, "Must be set");
        if (_hasUserLimit) {
            require(
                _poolLimitPerUser > poolLimitPerUser,
                "New limit must be higher"
            );
            poolLimitPerUser = _poolLimitPerUser;
        } else {
            hasUserLimit = _hasUserLimit;
            poolLimitPerUser = 0;
        }
        emit NewPoolLimit(poolLimitPerUser);
    }

    /// @notice Update reward per block
    /// @dev Only callable by owner.
    /// @param _rewardPerBlock The reward per block
    function updateRewardPerBlock(uint256 _rewardPerBlock) external onlyOwner {
        _updatePool();

        rewardPerBlock = _rewardPerBlock;
        emit NewRewardPerBlock(_rewardPerBlock);
    }

    /// @notice It allows the admin to update start and end blocks
    /// @dev This function is only callable by owner.
    /// @param _startBlock The new start block
    /// @param _bonusEndBlock The new end block
    function updateStartAndEndBlocks(
        uint256 _startBlock,
        uint256 _bonusEndBlock
    ) external onlyOwner {
        require(
            _startBlock < _bonusEndBlock,
            "New startBlock must be lower than new endBlock"
        );
        require(
            block.number < _startBlock,
            "New startBlock must be higher than current block"
        );

        startBlock = _startBlock;
        bonusEndBlock = _bonusEndBlock;

        // Set the lastRewardBlock as the startBlock
        lastRewardBlock = startBlock;

        emit NewStartAndEndBlocks(_startBlock, _bonusEndBlock);
    }

    /// @notice View function to see pending reward on frontend.
    /// @param _user User address
    /// @return uint256 Reward for a given user
    function pendingReward(address _user) external view returns (uint256) {
        UserInfo storage user = userInfo[_user];
        uint256 reward;
        if (block.number > lastRewardBlock && totalstakedAmount != 0) {
            uint256 multiplier = _getMultiplier(lastRewardBlock, block.number);
            uint256 vivReward = multiplier * rewardPerBlock;
            uint256 adjustedTokenPerShare = accTokenPerShare +
                ((vivReward * PRECISION_FACTOR) / totalstakedAmount);
            reward =
                (user.amount * adjustedTokenPerShare) /
                PRECISION_FACTOR -
                user.rewardDebt;
        } else {
            reward =
                (user.amount * accTokenPerShare) /
                PRECISION_FACTOR -
                user.rewardDebt;
        }
        return reward + user.rewardLockedUp;
    }

    /// @notice Update reward variables of the given pool to be up-to-date.
    function _updatePool() internal {
        if (block.number <= lastRewardBlock) {
            return;
        }

        if (totalstakedAmount == 0) {
            lastRewardBlock = block.number;
            return;
        }

        uint256 multiplier = _getMultiplier(lastRewardBlock, block.number);
        uint256 vivReward = multiplier * rewardPerBlock;
        accTokenPerShare += (vivReward * PRECISION_FACTOR) / totalstakedAmount;
        lastRewardBlock = block.number;
    }

    /// @notice Return reward multiplier over the given _from to _to block.
    /// @param _from Block to start
    /// @param _to Block to finish
    function _getMultiplier(
        uint256 _from,
        uint256 _to
    ) internal view returns (uint256) {
        if (_to <= bonusEndBlock) {
            return _to - _from;
        } else if (_from >= bonusEndBlock) {
            return 0;
        } else {
            return bonusEndBlock - _from;
        }
    }

    function rewardDuration() public view returns (uint256) {
        return bonusEndBlock - startBlock;
    }

    function depositReward(uint256 _amount) external onlyOwner {
        rewardToken.transferFrom(owner(), address(this), _amount);
        totalRewards += _amount;
    }

    function setTotalReward(uint256 _amount) external onlyOwner {
        totalRewards = _amount;
    }

    function calcRewardPerBlock() public onlyOwner {
        require(block.number < startBlock, "Pool has started");
        rewardPerBlock = totalRewards / rewardDuration();
    }
}

Read Contract

PRECISION_FACTOR 0xccd34cd5 → uint256
SMART_CHEF_FACTORY 0xbd617191 → address
accTokenPerShare 0x8f662915 → uint256
bonusEndBlock 0x1aed6553 → uint256
hasUserLimit 0x92e8990e → bool
isInitialized 0x392e53cd → bool
lastRewardBlock 0xa9f8d181 → uint256
minDeposit 0x41b3d185 → uint256
owner 0x8da5cb5b → address
pendingReward 0xf40f0f52 → uint256
poolLimitPerUser 0x66fe9f8a → uint256
rewardDuration 0xf520e7e5 → uint256
rewardPerBlock 0x8ae39cac → uint256
rewardToken 0xf7c618c1 → address
stakedToken 0xcc7a262e → address
startBlock 0x48cd4cb1 → uint256
totalRewards 0x0e15561a → uint256
totalstakedAmount 0x7a988f97 → uint256
userInfo 0x1959a002 → uint256, uint256, uint256, uint256, uint256

Write Contract 17 functions

These functions modify contract state and require a wallet transaction to execute.

calcRewardPerBlock 0x01a0011f
No parameters
changeMinDeposit 0x4b2a12da
uint256 _minDeposit
clearStuckBalance 0x56a227f2
uint256 amountPercentage
address _walletAddress
deposit 0xb6b55f25
uint256 _amount
depositReward 0x1e2720ff
uint256 _amount
emergencyRewardWithdraw 0x3279beab
uint256 _amount
emergencyWithdraw 0xdb2e21bc
No parameters
initialize 0xc0eca2a4
uint256 _minDeposit
address _stakedToken
address _rewardToken
uint256 _rewardPerBlock
uint256 _startBlock
uint256 _bonusEndBlock
uint256 _poolLimitPerUser
recoverWrongTokens 0x3f138d4b
address _tokenAddress
uint256 _tokenAmount
renounceOwnership 0x715018a6
No parameters
setTotalReward 0xbc78f0d5
uint256 _amount
stopReward 0x80dc0672
No parameters
transferOwnership 0xf2fde38b
address newOwner
updatePoolLimitPerUser 0xa0b40905
bool _hasUserLimit
uint256 _poolLimitPerUser
updateRewardPerBlock 0x01f8a976
uint256 _rewardPerBlock
updateStartAndEndBlocks 0x9513997f
uint256 _startBlock
uint256 _bonusEndBlock
withdraw 0x2e1a7d4d
uint256 _amount

Recent Transactions

No transactions found for this address