Address Contract Partially Verified
Address
0x2D168651d85fE8B16aeBF42272A9b64f24ac3603
Balance
0 ETH
Nonce
1
Code Size
20669 bytes
Creator
0x2Bea4Cb4...28B5 at tx 0x490cbf3b...aea550
Indexed Transactions
0
Contract Bytecode
20669 bytes
0x608060405234801561001057600080fd5b506004361061027f5760003560e01c80638456cb591161015c578063cdd033c8116100ce578063dd4be68311610087578063dd4be68314610d3e578063e0a79b1614610da2578063e5c4686914610dc8578063f2fde38b14610dd0578063f94e5c8814610df6578063fbfcd24114610f195761027f565b8063cdd033c814610a9a578063d0cd4ee014610ad2578063d431350614610af8578063d43c953514610b35578063d768779a14610cda578063d939381414610d125761027f565b8063a4f3f0e511610120578063a4f3f0e51461084e578063b104e006146108ff578063b2bdfa7b1461091c578063bf6eac2f14610924578063c549e6b91461095a578063c922e937146109625761027f565b80638456cb59146107de57806385d895ef146107e657806388125f79146107ee57806396591e311461080b578063a019cb4b146108285761027f565b8063486ff0cd116101f5578063572b6c05116101b9578063572b6c05146107725780635c975abb146107985780635f96dc11146107a0578063715018a6146107a85780637bdb8cd3146107b05780637da0a877146107d65761027f565b8063486ff0cd146106445780634cd36531146106c15780634f64b2be146106fd5780635058c4601461071a578063539cd3b4146107465761027f565b80631d2002e7116102475780631d2002e7146103c157806326fa24e9146103de57806328523eb6146105b15780633f4ba83a146105f357806340a16688146105fb57806340f02ab61461063c5761027f565b806301193ad71461028457806301bc45c91461032757806304a624c61461034b5780631320da8b14610365578063187739a414610393575b600080fd5b6103256004803603602081101561029a57600080fd5b810190602081018135600160201b8111156102b457600080fd5b8201836020820111156102c657600080fd5b803590602001918460208302840111600160201b831117156102e757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610f21945050505050565b005b61032f6110df565b604080516001600160a01b039092168252519081900360200190f35b6103536110ee565b60408051918252519081900360200190f35b6103536004803603604081101561037b57600080fd5b506001600160a01b03813581169160200135166110f4565b610353600480360360408110156103a957600080fd5b506001600160a01b0381358116916020013516611111565b610325600480360360208110156103d757600080fd5b503561112e565b610404600480360360208110156103f457600080fd5b50356001600160a01b03166111c8565b6040518080602001806020018060200180602001806020018060200187810387528d818151815260200191508051906020019060200280838360005b83811015610458578181015183820152602001610440565b5050505090500187810386528c818151815260200191508051906020019060200280838360005b8381101561049757818101518382015260200161047f565b5050505090500187810385528b818151815260200191508051906020019060200280838360005b838110156104d65781810151838201526020016104be565b5050505090500187810384528a818151815260200191508051906020019060200280838360005b838110156105155781810151838201526020016104fd565b50505050905001878103835289818151815260200191508051906020019060200280838360005b8381101561055457818101518382015260200161053c565b50505050905001878103825288818151815260200191508051906020019060200280838360005b8381101561059357818101518382015260200161057b565b505050509050019c5050505050505050505050505060405180910390f35b6105df600480360360408110156105c757600080fd5b506001600160a01b038135811691602001351661143e565b604080519115158252519081900360200190f35b6105df61145e565b6105df600480360360a081101561061157600080fd5b5080356001600160a01b0316906020810135906040810135906060810135906080013560ff166114c7565b610353611627565b61064c61162d565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561068657818101518382015260200161066e565b50505050905090810190601f1680156106b35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610353600480360360808110156106d757600080fd5b508035906001600160a01b03602082013581169160408101359091169060600135611648565b61032f6004803603602081101561071357600080fd5b503561172e565b6103256004803603604081101561073057600080fd5b506001600160a01b038135169060200135611758565b61032f6004803603604081101561075c57600080fd5b506001600160a01b03813516906020013561197f565b6105df6004803603602081101561078857600080fd5b50356001600160a01b03166119b7565b6105df6119cb565b6103536119db565b6103256119e1565b610353600480360360208110156107c657600080fd5b50356001600160a01b0316611aae565b61032f611ac0565b6105df611acf565b610353611b31565b6103256004803603602081101561080457600080fd5b5035611b37565b6103256004803603602081101561082157600080fd5b5035611bd1565b61032f6004803603602081101561083e57600080fd5b50356001600160a01b0316611c6b565b6103256004803603604081101561086457600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561088e57600080fd5b8201836020820111156108a057600080fd5b803590602001918460208302840111600160201b831117156108c157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611c86945050505050565b6103536004803603602081101561091557600080fd5b5035611f66565b61032f611f87565b6103256004803603606081101561093a57600080fd5b506001600160a01b03813581169160208101359091169060400135611f96565b610353612704565b6103256004803603608081101561097857600080fd5b8135916001600160a01b0360208201351691810190606081016040820135600160201b8111156109a757600080fd5b8201836020820111156109b957600080fd5b803590602001918460208302840111600160201b831117156109da57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610a2957600080fd5b820183602082011115610a3b57600080fd5b803590602001918460208302840111600160201b83111715610a5c57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061270b945050505050565b61032560048036036060811015610ab057600080fd5b506001600160a01b038135811691602081013590911690604001351515612e68565b61032560048036036020811015610ae857600080fd5b50356001600160a01b0316612fbf565b61032560048036036080811015610b0e57600080fd5b506001600160a01b038135169060ff60208201351690604081013590606001351515613039565b61032560048036036060811015610b4b57600080fd5b810190602081018135600160201b811115610b6557600080fd5b820183602082011115610b7757600080fd5b803590602001918460208302840111600160201b83111715610b9857600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610be757600080fd5b820183602082011115610bf957600080fd5b803590602001918460208302840111600160201b83111715610c1a57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610c6957600080fd5b820183602082011115610c7b57600080fd5b803590602001918460208302840111600160201b83111715610c9c57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061326b945050505050565b61032560048036036080811015610cf057600080fd5b506001600160a01b038135169060208101359060408101359060600135613516565b6105df60048036036040811015610d2857600080fd5b506001600160a01b038135169060200135613646565b610d6460048036036020811015610d5457600080fd5b50356001600160a01b0316613c75565b60408051971515885260ff9096166020880152868601949094526060860192909252608085015260a0840152151560c0830152519081900360e00190f35b61035360048036036020811015610db857600080fd5b50356001600160a01b0316613cb9565b610353613ccb565b61032560048036036020811015610de657600080fd5b50356001600160a01b0316613cd1565b6105df60048036036040811015610e0c57600080fd5b810190602081018135600160201b811115610e2657600080fd5b820183602082011115610e3857600080fd5b803590602001918460208302840111600160201b83111715610e5957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610ea857600080fd5b820183602082011115610eba57600080fd5b803590602001918460208302840111600160201b83111715610edb57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550613dca945050505050565b610353613fbf565b610f29613fc5565b6001546001600160a01b03908116911614610f79576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b6040805160008152602081019182905251610f9691600991614e71565b5060005b81518160ff16101561105d57600a54600090610fb99062015180613ff7565b9050828260ff1681518110610fca57fe5b6020026020010151811161101c576040805162461bcd60e51b8152602060048201526014602482015273496e76616c696420496e74657276616c2044617960601b604482015290519081900360640190fd5b6009838360ff168151811061102d57fe5b60209081029190910181015182546001818101855560009485529290932090920191909155919091019050610f9a565b507f29635226d0b00834767b0cf38daca8dc0fe978152b0a8a5b39eb281126352361600942604051808060200183815260200182810382528481815481526020019150805480156110cd57602002820191906000526020600020905b8154815260200190600101908083116110b9575b5050935050505060405180910390a150565b6002546001600160a01b031681565b600c5481565b600e60209081526000928352604080842090915290825290205481565b600760209081526000928352604080842090915290825290205481565b611136613fc5565b6001546001600160a01b03908116911614611186576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b600b8190556040805182815242602082015281517f886f1c6ee47e76ca7e1c7715d9662c5cbc03a9215b76899c702e3d1c38d1ee43929181900390910190a150565b6001600160a01b0381166000908152600d6020908152604091829020600281018054845181850281018501909552808552606094859485948594859485949193600384019360018101936004820193600583019360069093019288919083018282801561125e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611240575b50505050509550848054806020026020016040519081016040528092919081815260200182805480156112ba57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161129c575b505050505094508380548060200260200160405190810160405280929190818152602001828054801561132c57602002820191906000526020600020906000905b825461010083900a900460ff1615158152602060019283018181049485019490930390920291018084116112fb5790505b505050505093508280548060200260200160405190810160405280929190818152602001828054801561137e57602002820191906000526020600020905b81548152602001906001019080831161136a575b50505050509250818054806020026020016040519081016040528092919081815260200182805480156113d057602002820191906000526020600020905b8154815260200190600101908083116113bc575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561142257602002820191906000526020600020905b81548152602001906001019080831161140e575b5050505050905095509550955095509550955091939550919395565b600860209081526000928352604080842090915290825290205460ff1681565b6000611468613fc5565b6001546001600160a01b039081169116146114b8576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b6114c0614040565b5060015b90565b60006114d1613fc5565b6001546001600160a01b03908116911614611521576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b6001600160a01b03861660009081526005602052604090205460ff1661158d57600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b0388161790555b6001600160a01b0386166000818152600560209081526040918290208054600160ff19909116811761ff00191661010060ff891602178255810189905560028101889055600301869055815188815290810187905280820186905242606082015290517f6b9e42b75b3aa79aee18ba04bd3f6dedba2d3e55228fadb89fd22817f7ef81ac916080908290030190a250600195945050505050565b600a5481565b6040805180820190915260018152603160f81b602082015290565b6001600160a01b038316600090815260056020819052604082200154819060ff16156116eb57600c5461167c9087906140e3565b955061169e6116976001600c5461413c90919063ffffffff16565b87906140e3565b90506116e46116ad848361417e565b6001600160a01b038088166000908152600760209081526040808320938a16835292905220546116de9089906140e3565b90613ff7565b9150611725565b6001600160a01b038086166000908152600760209081526040808320938816835292905220546117229084906116de9089906140e3565b91505b50949350505050565b6003818154811061173e57600080fd5b6000918252602090912001546001600160a01b0316905081565b611760613fc5565b6001546001600160a01b039081169116146117b0576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b80826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156117fe57600080fd5b505afa158015611812573d6000803e3d6000fd5b505050506040513d602081101561182857600080fd5b50511015611874576040805162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742042616c616e636560601b604482015290519081900360640190fd5b6001546040805163a9059cbb60e01b81526001600160a01b0392831660048201526024810184905290519184169163a9059cbb916044808201926020929091908290030181600087803b1580156118ca57600080fd5b505af11580156118de573d6000803e3d6000fd5b505050506040513d60208110156118f457600080fd5b5051611939576040805162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b6040805182815242602082015281516001600160a01b038516927fcb92e2679de255302c9b8d0673cbdf8ef54667e943bf8f049bcaf6a85926ba1a928290030190a25050565b6004602052816000526040600020818154811061199b57600080fd5b6000918252602090912001546001600160a01b03169150829050565b6000546001600160a01b0390811691161490565b600054600160a01b900460ff1690565b60105481565b6119e9613fc5565b6002546001600160a01b03908116911614611a4b576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f74207468652041646d696e604482015290519081900360640190fd5b6002546001546040516001600160a01b0392831692909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600254600180546001600160a01b0319166001600160a01b03909216919091179055565b60066020526000908152604090205481565b6000546001600160a01b031681565b6000611ad9613fc5565b6001546001600160a01b03908116911614611b29576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b6114c06141d8565b60035490565b611b3f613fc5565b6001546001600160a01b03908116911614611b8f576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b600a8190556040805182815242602082015281517ff676bd50ed08b41fe017c9b4b7606b132ed9afafd39cbe090006c602170638bf929181900390910190a150565b611bd9613fc5565b6001546001600160a01b03908116911614611c29576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b600c8190556040805182815242602082015281517fd9124f37a22fb221df30d124c79aae3c3be0e56338cc2ed4d68ade2a51319f49929181900390910190a150565b600d602052600090815260409020546001600160a01b031681565b611c8e613fc5565b6001546001600160a01b03908116911614611cde576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b60408051600080825260208083018085526001600160a01b038716835260049091529290209051611d0f9290614ebc565b506001600160a01b03821660009081526005602052604090205460ff16611d76576040805162461bcd60e51b815260206004820152601660248201527514dd185ad95908151bdad95b88139bdd08115e1a5cdd60521b604482015290519081900360640190fd5b60005b81518160ff161015611ebf5760035482511115611dcd576040805162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a5908125b9c1d5d609a1b604482015290519081900360640190fd5b60056000838360ff1681518110611de057fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16611e51576040805162461bcd60e51b815260206004820152601660248201527514995dd85c9908151bdad95b88139bdd08115e1a5cdd60521b604482015290519081900360640190fd5b6001600160a01b03831660009081526004602052604090208251839060ff8416908110611e7a57fe5b60209081029190910181015182546001808201855560009485529290932090920180546001600160a01b0319166001600160a01b039093169290921790915501611d79565b506001600160a01b03821660008181526004602090815260409182902082514292810183905283815281549381018490527f533d99224d362fcbe71ce5ff0a8b2d61a9c08b8d1df27aab851edb881f3fb16b939192918190606082019085908015611f5357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611f35575b5050935050505060405180910390a25050565b60098181548110611f7657600080fd5b600091825260209091200154905081565b6001546001600160a01b031681565b611f9e6119cb565b15611fe3576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b826001600160a01b0316611ff5613fc5565b6001600160a01b03161415612051576040805162461bcd60e51b815260206004820152601f60248201527f5354414b453a20696e76616c6964207265666572726572206164647265737300604482015290519081900360640190fd5b6001600160a01b03821660009081526005602052604090205460ff166120be576040805162461bcd60e51b815260206004820152601a60248201527f5354414b45203a20546f6b656e206973206e6f74204578697374000000000000604482015290519081900360640190fd5b6001600160a01b0382166000908152600560205260408120600101549061211c908390600e906120ec613fc5565b6001600160a01b03908116825260208083019390935260409182016000908120918916815292529020549061417e565b10156121595760405162461bcd60e51b815260040180806020018281038252602a815260200180614ff8602a913960400191505060405180910390fd5b6001600160a01b03821660009081526005602052604081206002015490612187908390600e906120ec613fc5565b11156121c45760405162461bcd60e51b815260040180806020018281038252602a815260200180614fce602a913960400191505060405180910390fd5b6001600160a01b038216600090815260056020908152604080832060030154600f909252909120546121f6908361417e565b1115612249576040805162461bcd60e51b815260206004820152601860248201527f5354414b45203a204d61786c696d697420657863656564730000000000000000604482015290519081900360640190fd5b42612261600a5460105461417e90919063ffffffff16565b116122b3576040805162461bcd60e51b815260206004820152601d60248201527f5354414b453a205374616b696e672054696d6520436f6d706c65746564000000604482015290519081900360640190fd5b600d60006122bf613fc5565b6001600160a01b03166001600160a01b03168152602001908152602001600020600401600d60006122ee613fc5565b6001600160a01b03168152602080820192909252604001600090812060040154835460018101855593825291812090920155600d9061232b613fc5565b6001600160a01b031681526020808201929092526040016000908120600190810180549182018155825290829020918104909101805460ff601f9093166101000a9283021916909117905561237e613fc5565b600d600061238a613fc5565b6001600160a01b0390811682526020820192909252604001600090812080546001600160a01b03191693909216929092179055600d906123c8613fc5565b6001600160a01b03908116825260208083019390935260409091016000908120600201805460018101825590825292812090920180546001600160a01b031916918616919091179055600d9061241c613fc5565b6001600160a01b03908116825260208083019390935260409091016000908120600301805460018101825590825292812090920180546001600160a01b031916918516919091179055600d90612470613fc5565b6001600160a01b031681526020808201929092526040016000908120600601805460018101825590825291812042920191909155600d906124af613fc5565b6001600160a01b039081168252602080830193909352604091820160009081206005018054600181018255908252848220018590559085168152600f9092529020546124fb908261417e565b6001600160a01b0383166000908152600f6020526040812091909155612558908290600e90612528613fc5565b6001600160a01b03908116825260208083019390935260409182016000908120918816815292529020549061417e565b600e6000612564613fc5565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120919091556323b872dd6125a1613fc5565b30846040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b031681526020018281526020019350505050602060405180830381600087803b1580156125f957600080fd5b505af115801561260d573d6000803e3d6000fd5b505050506040513d602081101561262357600080fd5b5051612668576040805162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8811985a5b1959608a1b604482015290519081900360640190fd5b816001600160a01b0316836001600160a01b0316612684613fc5565b6001600160a01b03167f8d0a98609f00f26e55cd12ea38ffb8a0dfad170f6f001d682185fdce4ff424446126e26001600d60006126bf613fc5565b6001600160a01b031681526020810191909152604001600020600401549061413c565b60408051918252602082018790524282820152519081900360600190a4505050565b6201518081565b612713613fc5565b6001546001600160a01b03908116911614612763576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b6001600160a01b0383166000908152600d6020526040812060050180548690811061278a57fe5b90600052602060002001541180156127ec57506001600160a01b0383166000908152600d602052604090206001018054859081106127c457fe5b90600052602060002090602091828204019190069054906101000a900460ff16151560011515145b6128275760405162461bcd60e51b81526004018080602001828103825260348152602001806150546034913960400191505060405180910390fd5b6001600160a01b0383166000908152600d6020526040902060050180548590811061284e57fe5b9060005260206000200154600d6000856001600160a01b03166001600160a01b03168152602001908152602001600020600301858154811061288c57fe5b60009182526020918290200154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b1580156128db57600080fd5b505afa1580156128ef573d6000803e3d6000fd5b505050506040513d602081101561290557600080fd5b5051101561295a576040805162461bcd60e51b815260206004820181905260248201527f454d455247454e4359203a20496e73756666696369656e742042616c616e6365604482015290519081900360640190fd5b6001600160a01b0383166000908152600d6020526040812060050180548690811061298157fe5b906000526020600020015490506000600d6000866001600160a01b03166001600160a01b0316815260200190815260200160002060010186815481106129c357fe5b90600052602060002090602091828204019190066101000a81548160ff0219169083151502179055506000600d6000866001600160a01b03166001600160a01b031681526020019081526020016000206005018681548110612a2157fe5b60009182526020808320909101929092556001600160a01b0386168152600d90915260409020600301805486908110612a5657fe5b60009182526020808320909101546040805163a9059cbb60e01b81526001600160a01b038981166004830152602482018790529151919092169363a9059cbb93604480850194919392918390030190829087803b158015612ab657600080fd5b505af1158015612aca573d6000803e3d6000fd5b505050506040513d6020811015612ae057600080fd5b50600090505b8351811015612ddb576000838281518110612afd57fe5b6020026020010151905060006001600160a01b0316600d6000886001600160a01b03166001600160a01b031681526020019081526020016000206002018881548110612b4557fe5b6000918252602090912001546001600160a01b031614612d6d576000612b8368056bc75e2d631000006116de600b54856140e390919063ffffffff16565b9050612b8f828261413c565b9150858381518110612b9d57fe5b60200260200101516001600160a01b031663a9059cbb600d60008a6001600160a01b03166001600160a01b031681526020019081526020016000206002018a81548110612be657fe5b6000918252602080832090910154604080516001600160e01b031960e087901b1681526001600160a01b039092166004830152602482018790525160448083019491928390030190829087803b158015612c3f57600080fd5b505af1158015612c53573d6000803e3d6000fd5b505050506040513d6020811015612c6957600080fd5b5051612cbc576040805162461bcd60e51b815260206004820152601b60248201527f454d455247454e4359203a205472616e73666572204661696c65640000000000604482015290519081900360640190fd5b858381518110612cc857fe5b60200260200101516001600160a01b0316876001600160a01b0316600d60008a6001600160a01b03166001600160a01b031681526020019081526020016000206002018a81548110612d1657fe5b6000918252602091829020015460408051868152429381019390935280516001600160a01b03909216927fcc30edb66a991e48ca3676c277d3a35485ebfaf3016fa9536663b2689c8f5eef929081900390910190a4505b6001600160a01b0386166000908152600d602052604090206003018054612dd29188918a908110612d9a57fe5b9060005260206000200160009054906101000a90046001600160a01b0316878581518110612dc457fe5b602002602001015184614261565b50600101612ae6565b506001600160a01b0384166000908152600d60205260409020600301805486908110612e0357fe5b60009182526020918290200154604080518481524293810193909352828101889052516001600160a01b0391821692918716917fa4b627609e711628747558b171b04b9636337afdadac065ee7113fb91eab0b72919081900360600190a35050505050565b612e70613fc5565b6001546001600160a01b03908116911614612ec0576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b6001600160a01b03831660009081526005602052604090205460ff168015612f0057506001600160a01b03821660009081526005602052604090205460ff165b612f43576040805162461bcd60e51b815260206004820152600f60248201526e151bdad95b881b9bdd08195e1a5cdd608a1b604482015290519081900360640190fd5b6001600160a01b03838116600081815260086020908152604080832094871680845294825291829020805460ff19168615151790819055825160ff90911615158152429181019190915281517f38dc54047237de43b07dc5d3a0cd9a29485be07da55d5611ddc91102542938ad929181900390910190a3505050565b612fc7613fc5565b6001546001600160a01b03908116911614613017576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b613041613fc5565b6001546001600160a01b03908116911614613091576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b8260ff16600114806130a657508260ff166002145b806130b457508260ff166003145b613105576040805162461bcd60e51b815260206004820152601760248201527f496e76616c6964204c6f636b61626c6520537461747573000000000000000000604482015290519081900360640190fd5b6001600160a01b03841660009081526005602052604090205460ff161515600114613169576040805162461bcd60e51b815260206004820152600f60248201526e151bdad95b88139bdd08115e1a5cdd608a1b604482015290519081900360640190fd5b8260ff16600114156131a05761317f428361417e565b6001600160a01b038516600090815260056020526040902060040155613202565b8260ff16600214156131cd576001600160a01b038416600090815260056020526040812060040155613202565b8260ff1660031415613202576001600160a01b038416600090815260056020819052604090912001805460ff19168215151790555b6001600160a01b0384166000818152600560208181526040928390206004810154920154835192835260ff16151590820152428183015290517f4030f7d2425e172fe94d03a4cfd07dcdbc4909529bdf15d2732aa1559ff9be7c9181900360600190a250505050565b613273613fc5565b6001546001600160a01b039081169116146132c3576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b815183511480156132d5575080518251145b613316576040805162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a5908125b9c1d5d609a1b604482015290519081900360640190fd5b60005b83518160ff1610156135105760056000858360ff168151811061333857fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1680156133a1575060056000848360ff168151811061337957fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff165b6133e4576040805162461bcd60e51b815260206004820152600f60248201526e151bdad95b881b9bdd08195e1a5cdd608a1b604482015290519081900360640190fd5b818160ff16815181106133f357fe5b602002602001015160076000868460ff168151811061340e57fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000858460ff168151811061344757fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002081905550828160ff168151811061348257fe5b60200260200101516001600160a01b0316848260ff16815181106134a257fe5b60200260200101516001600160a01b03167f2dc18c352fdd373a4dc83a7156d0dfe95082bd4d820bda50fa65ee3bcf8648f3848460ff16815181106134e357fe5b602002602001015142604051808381526020018281526020019250505060405180910390a3600101613319565b50505050565b61351e613fc5565b6001546001600160a01b0390811691161461356e576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b6001600160a01b03841660009081526005602052604090205460ff166135cd576040805162461bcd60e51b815260206004820152600f60248201526e151bdad95b88139bdd08115e1a5cdd608a1b604482015290519081900360640190fd5b6001600160a01b0384166000818152600560209081526040918290206001810187905560028101869055600301849055815186815290810185905280820184905242606082015290517f6b9e42b75b3aa79aee18ba04bd3f6dedba2d3e55228fadb89fd22817f7ef81ac9181900360800190a250505050565b60006136506119cb565b15613695576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b826001600160a01b03166136a7613fc5565b6001600160a01b031614806136d657506001546001600160a01b03166136cb613fc5565b6001600160a01b0316145b613727576040805162461bcd60e51b815260206004820152601b60248201527f554e5354414b453a20496e76616c6964205573657220456e7472790000000000604482015290519081900360640190fd5b6001600160a01b0383166000908152600d6020526040812060030180548490811061374e57fe5b60009182526020808320909101546001600160a01b031680835260059091526040909120600401549091504210156137c5576040805162461bcd60e51b8152602060048201526015602482015274155394d51052d14e88151bdad95b88131bd8dad959605a1b604482015290519081900360640190fd5b6001600160a01b0381166000908152600560208190526040909120015460ff1615613890574261383d600a54600d6000886001600160a01b03166001600160a01b03168152602001908152602001600020600601868154811061382457fe5b906000526020600020015461417e90919063ffffffff16565b1115613890576040805162461bcd60e51b815260206004820181905260248201527f554e5354414b453a204c6f636b656420696e206f7074696f6e616c206c6f636b604482015290519081900360640190fd5b6001600160a01b0384166000908152600d602052604081206005018054859081106138b757fe5b9060005260206000200154118061391857506001600160a01b0384166000908152600d602052604090206001018054849081106138f057fe5b90600052602060002090602091828204019190069054906101000a900460ff16151560011515145b6139535760405162461bcd60e51b81526004018080602001828103825260328152602001806150226032913960400191505060405180910390fd5b6001600160a01b0384166000908152600d6020526040812060050180548590811061397a57fe5b60009182526020808320909101546001600160a01b038086168452600f8352604080852054918a168552600d909352918320600501805491945091929190879081106139c257fe5b60009182526020808320909101929092556001600160a01b0388168152600d909152604081206001018054879081106139f757fe5b90600052602060002090602091828204019190066101000a81548160ff02191690831515021790555081600d6000886001600160a01b03166001600160a01b031681526020019081526020016000206003018681548110613a5457fe5b60009182526020918290200154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015613aa357600080fd5b505afa158015613ab7573d6000803e3d6000fd5b505050506040513d6020811015613acd57600080fd5b50511015613b22576040805162461bcd60e51b815260206004820152601e60248201527f554e5354414b45203a20496e73756666696369656e742042616c616e63650000604482015290519081900360640190fd5b6001600160a01b0386166000908152600d60205260409020600301805486908110613b4957fe5b60009182526020808320909101546040805163a9059cbb60e01b81526001600160a01b038b81166004830152602482018890529151919092169363a9059cbb93604480850194919392918390030190829087803b158015613ba957600080fd5b505af1158015613bbd573d6000803e3d6000fd5b505050506040513d6020811015613bd357600080fd5b50613be2905086868484614420565b6001600160a01b0386166000908152600d60205260409020600301805486908110613c0957fe5b60009182526020918290200154604080518581524293810193909352828101889052516001600160a01b0391821692918916917fa4b627609e711628747558b171b04b9636337afdadac065ee7113fb91eab0b72919081900360600190a3600193505050505b92915050565b600560208190526000918252604090912080546001820154600283015460038401546004850154949095015460ff8085169661010090950481169593949293911687565b600f6020526000908152604090205481565b600b5481565b613cd9613fc5565b6001546001600160a01b03908116911614613d29576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b6001600160a01b038116613d6e5760405162461bcd60e51b8152600401808060200182810382526026815260200180614f456026913960400191505060405180910390fd5b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000613dd4613fc5565b6001546001600160a01b03908116911614613e24576040805162461bcd60e51b81526020600482018190526024820152600080516020614fae833981519152604482015290519081900360640190fd5b8151835114613e6d576040805162461bcd60e51b815260206004820152601060248201526f496e76616c696420656c656d656e747360801b604482015290519081900360640190fd5b60005b83518160ff161015613fb55760056000858360ff1681518110613e8f57fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16613efc576040805162461bcd60e51b8152602060048201526012602482015271151bdad95b881a5cc81b9bdd08195e1a5cdd60721b604482015290519081900360640190fd5b6000838260ff1681518110613f0d57fe5b602002602001015111613f5f576040805162461bcd60e51b8152602060048201526015602482015274125b9d985b1a590814995dd85c9908105b5bdd5b9d605a1b604482015290519081900360640190fd5b828160ff1681518110613f6e57fe5b602002602001015160066000868460ff1681518110613f8957fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002055600101613e70565b5060019392505050565b610e1081565b600060183610801590613fdc5750613fdc336119b7565b15613ff0575060131936013560601c6114c4565b50336114c4565b600061403983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506144d5565b9392505050565b6140486119cb565b614090576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6140c6613fc5565b604080516001600160a01b039092168252519081900360200190a1565b6000826140f257506000613c6f565b828202828482816140ff57fe5b04146140395760405162461bcd60e51b8152600401808060200182810382526021815260200180614f8d6021913960400191505060405180910390fd5b600061403983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614577565b600082820183811015614039576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6141e06119cb565b15614225576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586140c6613fc5565b6001600160a01b03821615613510576001600160a01b0382166000908152600660205260409020548111156142c75760405162461bcd60e51b8152600401808060200182810382526022815260200180614f6b6022913960400191505060405180910390fd5b6001600160a01b0382166000908152600660205260409020546142ea908261413c565b6001600160a01b03808416600081815260066020908152604080832095909555845163a9059cbb60e01b81529389166004850152602484018690529351919363a9059cbb936044808201949293918390030190829087803b15801561434e57600080fd5b505af1158015614362573d6000803e3d6000fd5b505050506040513d602081101561437857600080fd5b50516143bd576040805162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b816001600160a01b0316836001600160a01b0316856001600160a01b03167fcd5e4f020ddad29434c2200a9edf2f8d7ec30f0d787f03b528ab7279aab0acbe8442604051808381526020018281526020019250505060405180910390a450505050565b60008061443a600a5460105461417e90919063ffffffff16565b91504282111561444b57504261445d565b600a5460105461445a9161417e565b90505b6001600160a01b0386166000908152600d6020526040902060060180546144a391908790811061448957fe5b90600052602060002001548261413c90919063ffffffff16565b91506144ad614f11565b84815260208101849052610e1083106144cc576144cc878783866145d1565b50505050505050565b600081836145615760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561452657818101518382015260200161450e565b50505050905090810190601f1680156145535780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161456d57fe5b0495945050505050565b600081848411156145c95760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561452657818101518382015260200161450e565b505050900390565b6000806145dc614f11565b6145e884610e10613ff7565b60208201526145fa8462015180613ff7565b815284516001600160a01b0388166000908152600d6020526040902060030180546146979261468c9290918a90811061462f57fe5b60009182526020808320909101546001600160a01b038d81168452600d909252604090922060030180549190921691908b90811061466957fe5b6000918252602090912001546001600160a01b03168960015b6020020151611648565b6020830151906140e3565b6001600160a01b0388166000908152600d6020526040812060020180549295509091889081106146c357fe5b6000918252602090912001546001600160a01b031614614918576146ff68056bc75e2d631000006116de600b54866140e390919063ffffffff16565b915061470b838361413c565b6001600160a01b0388166000908152600d602052604090206003018054919450908790811061473657fe5b60009182526020808320909101546001600160a01b038a81168452600d90925260409092206002018054919092169163a9059cbb918990811061477557fe5b6000918252602080832090910154604080516001600160e01b031960e087901b1681526001600160a01b039092166004830152602482018890525160448083019491928390030190829087803b1580156147ce57600080fd5b505af11580156147e2573d6000803e3d6000fd5b505050506040513d60208110156147f857600080fd5b50511515600114614842576040805162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8811985a5b1959608a1b604482015290519081900360640190fd5b6001600160a01b0387166000908152600d6020526040902060030180548790811061486957fe5b6000918252602090912001546001600160a01b0316614886613fc5565b6001600160a01b0316600d60008a6001600160a01b03166001600160a01b0316815260200190815260200160002060020188815481106148c257fe5b6000918252602091829020015460408051878152429381019390935280516001600160a01b03909216927fcc30edb66a991e48ca3676c277d3a35485ebfaf3016fa9536663b2689c8f5eef929081900390910190a45b6001600160a01b0387166000908152600d60205260409020600301805461499a9189918990811061494557fe5b60009182526020808320909101546001600160a01b038c81168452600d909252604090922060030180549190921691908a90811061497f57fe5b6000918252602090912001546001600160a01b031686614261565b60015b60095460ff82161015614e675760098160ff16815481106149ba57fe5b600091825260209091200154825110614e5d576000614a086018614a02600160098660ff16815481106149e957fe5b906000526020600020015461413c90919063ffffffff16565b906140e3565b90506000614a1e8285600160200201519061413c565b9050600060046000600d60008e6001600160a01b03166001600160a01b031681526020019081526020016000206003018c81548110614a5957fe5b60009182526020808320909101546001600160a01b031683528201929092526040019020805460ff8616908110614a8c57fe5b60009182526020808320909101546001600160a01b038e81168452600d909252604090922060030180549190921692508b908110614ac657fe5b6000918252602090912001546001600160a01b03828116911614801590614b4e57506001600160a01b038b166000908152600d60205260408120600301805460089291908d908110614b1457fe5b60009182526020808320909101546001600160a01b039081168452838201949094526040928301822093851682529290925290205460ff16155b15614e4f5788516001600160a01b038c166000908152600d602052604090206003018054614bab92614ba49290918e908110614b8657fe5b6000918252602090912001546001600160a01b0316848d6001614682565b83906140e3565b6001600160a01b038c166000908152600d60205260408120600201805492995090918c908110614bd757fe5b6000918252602090912001546001600160a01b031614614e0657614c1368056bc75e2d631000006116de600b548a6140e390919063ffffffff16565b9550614c1f878761413c565b9650806001600160a01b031663a9059cbb600d60008e6001600160a01b03166001600160a01b031681526020019081526020016000206002018c81548110614c6357fe5b6000918252602080832090910154604080516001600160e01b031960e087901b1681526001600160a01b039092166004830152602482018c90525160448083019491928390030190829087803b158015614cbc57600080fd5b505af1158015614cd0573d6000803e3d6000fd5b505050506040513d6020811015614ce657600080fd5b50511515600114614d30576040805162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8811985a5b1959608a1b604482015290519081900360640190fd5b6001600160a01b038b166000908152600d6020526040902060030180548b908110614d5757fe5b6000918252602090912001546001600160a01b0316614d74613fc5565b6001600160a01b0316600d60008e6001600160a01b03166001600160a01b031681526020019081526020016000206002018c81548110614db057fe5b60009182526020918290200154604080518b8152429381019390935280516001600160a01b03909216927fcc30edb66a991e48ca3676c277d3a35485ebfaf3016fa9536663b2689c8f5eef929081900390910190a45b6001600160a01b038b166000908152600d602052604090206003018054614e4f918d918d908110614e3357fe5b6000918252602090912001546001600160a01b0316838a614261565b836001019350505050614e62565b614e67565b61499d565b5050505050505050565b828054828255906000526020600020908101928215614eac579160200282015b82811115614eac578251825591602001919060010190614e91565b50614eb8929150614f2f565b5090565b828054828255906000526020600020908101928215614eac579160200282015b82811115614eac57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614edc565b60405180604001604052806002906020820280368337509192915050565b5b80821115614eb85760008155600101614f3056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737353454e44203a20496e73756666696369656e74205265776172642042616c616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725354414b45203a204d617820416d6f756e742073686f756c642062652077697468696e207065726d69745354414b45203a204d696e20416d6f756e742073686f756c642062652077697468696e207065726d6974554e5354414b45203a20416c726561647920436c61696d656420286f722920496e73756666696369656e74205374616b6564454d455247454e4359203a20416c726561647920436c61696d656420286f722920496e73756666696369656e74205374616b6564a264697066735822122076c7fe17ab74a6f2bc65e1cc4ace360b5a67b50b88cd81f4c4185d84b71b527964736f6c63430007060033
Verified Source Code Partial Match
Compiler: v0.7.6+commit.7338295f
EVM: istanbul
Optimization: Yes (200 runs)
UnifarmV20.sol 1381 lines
// Sources flattened with hardhat v2.5.0 https://hardhat.org
// File contracts/forwarder/IRelayRecipient.sol
// SPDX-License-Identifier:MIT
pragma solidity ^0.7.6;
/**
* a contract must implement this interface in order to support relayed transaction.
* It is better to inherit the BaseRelayRecipient as its implementation.
*/
abstract contract IRelayRecipient {
/**
* return if the forwarder is trusted to forward relayed transactions to us.
* the forwarder is required to verify the sender's signature, and verify
* the call is not a replay.
*/
function isTrustedForwarder(address forwarder)
public
view
virtual
returns (bool);
/**
* return the sender of this call.
* if the call came through our trusted forwarder, then the real sender is appended as the last 20 bytes
* of the msg.data.
* otherwise, return `msg.sender`
* should be used in the contract anywhere instead of msg.sender
*/
function _msgSender() internal view virtual returns (address payable);
function versionRecipient() external view virtual returns (string memory);
}
// File contracts/forwarder/BaseRelayRecipient.sol
pragma solidity ^0.7.6;
/**
* A base contract to be inherited by any contract that want to receive relayed transactions
* A subclass must use "_msgSender()" instead of "msg.sender"
*/
abstract contract BaseRelayRecipient is IRelayRecipient {
/*
* Forwarder singleton we accept calls from
*/
address public trustedForwarder;
/*
* require a function to be called through GSN only
*/
modifier trustedForwarderOnly() {
require(
msg.sender == address(trustedForwarder),
"Function can only be called through the trusted Forwarder"
);
_;
}
function isTrustedForwarder(address forwarder)
public
view
override
returns (bool)
{
return forwarder == trustedForwarder;
}
/**
* return the sender of this call.
* if the call came through our trusted forwarder, return the original sender.
* otherwise, return `msg.sender`.
* should be used in the contract anywhere instead of msg.sender
*/
function _msgSender()
internal
view
virtual
override
returns (address payable ret)
{
if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {
// At this point we know that the sender is a trusted forwarder,
// so we trust that the last bytes of msg.data are the verified sender address.
// extract sender address from the end of msg.data
assembly {
ret := shr(96, calldataload(sub(calldatasize(), 20)))
}
} else {
return msg.sender;
}
}
}
// File contracts/abstract/Pausable.sol
pragma solidity >=0.6.0 <=0.8.0;
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is BaseRelayRecipient {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
// File contracts/abstract/Ownable.sol
pragma solidity >=0.6.0 <=0.8.0;
abstract contract Ownable is Pausable {
address public _owner;
address public _admin;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor(address ownerAddress) {
_owner = _msgSender();
_admin = ownerAddress;
emit OwnershipTransferred(address(0), _owner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyAdmin() {
require(_admin == _msgSender(), "Ownable: caller is not the Admin");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyAdmin {
emit OwnershipTransferred(_owner, _admin);
_owner = _admin;
}
/**
* @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 {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
// File contracts/libraries/SafeMath.sol
pragma solidity ^0.7.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;
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;
}
}
// File contracts/interfaces/IERC20.sol
pragma solidity ^0.7.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
);
}
// File contracts/abstract/Admin.sol
pragma solidity ^0.7.0;
abstract contract Admin is Ownable {
struct tokenInfo {
bool isExist;
uint8 decimal;
uint256 userMinStake;
uint256 userMaxStake;
uint256 totalMaxStake;
uint256 lockableDays;
bool optionableStatus;
}
using SafeMath for uint256;
address[] public tokens;
mapping(address => address[]) public tokensSequenceList;
mapping(address => tokenInfo) public tokenDetails;
mapping(address => uint256) public rewardCap;
mapping(address => mapping(address => uint256)) public tokenDailyDistribution;
mapping(address => mapping(address => bool)) public tokenBlockedStatus;
uint256[] public intervalDays = [1, 8, 15, 22];
uint256 public constant DAYS = 1 days;
uint256 public constant HOURS = 1 hours;
uint256 public stakeDuration;
uint256 public refPercentage;
uint256 public optionableBenefit;
event TokenDetails(
address indexed tokenAddress,
uint256 userMinStake,
uint256 userMaxStake,
uint256 totalMaxStake,
uint256 updatedTime
);
event LockableTokenDetails(
address indexed tokenAddress,
uint256 lockableDys,
bool optionalbleStatus,
uint256 updatedTime
);
event DailyDistributionDetails(
address indexed stakedTokenAddress,
address indexed rewardTokenAddress,
uint256 rewards,
uint256 time
);
event SequenceDetails(
address indexed stakedTokenAddress,
address[] rewardTokenSequence,
uint256 time
);
event StakeDurationDetails(uint256 updatedDuration, uint256 time);
event OptionableBenefitDetails(uint256 updatedBenefit, uint256 time);
event ReferrerPercentageDetails(uint256 updatedRefPercentage, uint256 time);
event IntervalDaysDetails(uint256[] updatedIntervals, uint256 time);
event BlockedDetails(
address indexed stakedTokenAddress,
address indexed rewardTokenAddress,
bool blockedStatus,
uint256 time
);
event WithdrawDetails(
address indexed tokenAddress,
uint256 withdrawalAmount,
uint256 time
);
constructor(address _owner) Ownable(_owner) {
stakeDuration = 90 days;
refPercentage = 2500000000000000000;
optionableBenefit = 2;
}
function addToken(
address tokenAddress,
uint256 userMinStake,
uint256 userMaxStake,
uint256 totalStake,
uint8 decimal
) public onlyOwner returns (bool) {
if (!(tokenDetails[tokenAddress].isExist)) tokens.push(tokenAddress);
tokenDetails[tokenAddress].isExist = true;
tokenDetails[tokenAddress].decimal = decimal;
tokenDetails[tokenAddress].userMinStake = userMinStake;
tokenDetails[tokenAddress].userMaxStake = userMaxStake;
tokenDetails[tokenAddress].totalMaxStake = totalStake;
emit TokenDetails(
tokenAddress,
userMinStake,
userMaxStake,
totalStake,
block.timestamp
);
return true;
}
function setDailyDistribution(
address[] memory stakedToken,
address[] memory rewardToken,
uint256[] memory dailyDistribution
) public onlyOwner {
require(
stakedToken.length == rewardToken.length &&
rewardToken.length == dailyDistribution.length,
"Invalid Input"
);
for (uint8 i = 0; i < stakedToken.length; i++) {
require(
tokenDetails[stakedToken[i]].isExist &&
tokenDetails[rewardToken[i]].isExist,
"Token not exist"
);
tokenDailyDistribution[stakedToken[i]][
rewardToken[i]
] = dailyDistribution[i];
emit DailyDistributionDetails(
stakedToken[i],
rewardToken[i],
dailyDistribution[i],
block.timestamp
);
}
}
function updateSequence(
address stakedToken,
address[] memory rewardTokenSequence
) public onlyOwner {
tokensSequenceList[stakedToken] = new address[](0);
require(tokenDetails[stakedToken].isExist, "Staked Token Not Exist");
for (uint8 i = 0; i < rewardTokenSequence.length; i++) {
require(rewardTokenSequence.length <= tokens.length, "Invalid Input");
require(
tokenDetails[rewardTokenSequence[i]].isExist,
"Reward Token Not Exist"
);
tokensSequenceList[stakedToken].push(rewardTokenSequence[i]);
}
emit SequenceDetails(
stakedToken,
tokensSequenceList[stakedToken],
block.timestamp
);
}
function updateToken(
address tokenAddress,
uint256 userMinStake,
uint256 userMaxStake,
uint256 totalStake
) public onlyOwner {
require(tokenDetails[tokenAddress].isExist, "Token Not Exist");
tokenDetails[tokenAddress].userMinStake = userMinStake;
tokenDetails[tokenAddress].userMaxStake = userMaxStake;
tokenDetails[tokenAddress].totalMaxStake = totalStake;
emit TokenDetails(
tokenAddress,
userMinStake,
userMaxStake,
totalStake,
block.timestamp
);
}
function lockableToken(
address tokenAddress,
uint8 lockableStatus,
uint256 lockedDays,
bool optionableStatus
) public onlyOwner {
require(
lockableStatus == 1 || lockableStatus == 2 || lockableStatus == 3,
"Invalid Lockable Status"
);
require(tokenDetails[tokenAddress].isExist == true, "Token Not Exist");
if (lockableStatus == 1) {
tokenDetails[tokenAddress].lockableDays = block.timestamp.add(lockedDays);
} else if (lockableStatus == 2) tokenDetails[tokenAddress].lockableDays = 0;
else if (lockableStatus == 3)
tokenDetails[tokenAddress].optionableStatus = optionableStatus;
emit LockableTokenDetails(
tokenAddress,
tokenDetails[tokenAddress].lockableDays,
tokenDetails[tokenAddress].optionableStatus,
block.timestamp
);
}
function updateStakeDuration(uint256 durationTime) public onlyOwner {
stakeDuration = durationTime;
emit StakeDurationDetails(stakeDuration, block.timestamp);
}
function updateOptionableBenefit(uint256 benefit) public onlyOwner {
optionableBenefit = benefit;
emit OptionableBenefitDetails(optionableBenefit, block.timestamp);
}
function updateRefPercentage(uint256 refPer) public onlyOwner {
refPercentage = refPer;
emit ReferrerPercentageDetails(refPercentage, block.timestamp);
}
function updateIntervalDays(uint256[] memory _interval) public onlyOwner {
intervalDays = new uint256[](0);
for (uint8 i = 0; i < _interval.length; i++) {
uint256 noD = stakeDuration.div(DAYS);
require(noD > _interval[i], "Invalid Interval Day");
intervalDays.push(_interval[i]);
}
emit IntervalDaysDetails(intervalDays, block.timestamp);
}
function changeTokenBlockedStatus(
address stakedToken,
address rewardToken,
bool status
) public onlyOwner {
require(
tokenDetails[stakedToken].isExist && tokenDetails[rewardToken].isExist,
"Token not exist"
);
tokenBlockedStatus[stakedToken][rewardToken] = status;
emit BlockedDetails(
stakedToken,
rewardToken,
tokenBlockedStatus[stakedToken][rewardToken],
block.timestamp
);
}
function safeWithdraw(address tokenAddress, uint256 amount) public onlyOwner {
require(
IERC20(tokenAddress).balanceOf(address(this)) >= amount,
"Insufficient Balance"
);
require(IERC20(tokenAddress).transfer(_owner, amount), "Transfer failed");
emit WithdrawDetails(tokenAddress, amount, block.timestamp);
}
function viewTokensCount() external view returns (uint256) {
return tokens.length;
}
function setRewardCap(
address[] memory tokenAddresses,
uint256[] memory rewards
) external onlyOwner returns (bool) {
require(tokenAddresses.length == rewards.length, "Invalid elements");
for (uint8 v = 0; v < tokenAddresses.length; v++) {
require(tokenDetails[tokenAddresses[v]].isExist, "Token is not exist");
require(rewards[v] > 0, "Invalid Reward Amount");
rewardCap[tokenAddresses[v]] = rewards[v];
}
return true;
}
}
// File contracts/UnifarmV20.sol
pragma solidity ^0.7.6;
/**
* @title Unifarm Contract
* @author OroPocket
*/
contract UnifarmV20 is Admin {
// Wrappers over Solidity's arithmetic operations
using SafeMath for uint256;
// Stores Stake Details
struct stakeInfo {
address user;
bool[] isActive;
address[] referrer;
address[] tokenAddress;
uint256[] stakeId;
uint256[] stakedAmount;
uint256[] startTime;
}
// Mapping
mapping(address => stakeInfo) public stakingDetails;
mapping(address => mapping(address => uint256)) public userTotalStaking;
mapping(address => uint256) public totalStaking;
uint256 public poolStartTime;
// Events
event Stake(
address indexed userAddress,
uint256 stakeId,
address indexed referrerAddress,
address indexed tokenAddress,
uint256 stakedAmount,
uint256 time
);
event Claim(
address indexed userAddress,
address indexed stakedTokenAddress,
address indexed tokenAddress,
uint256 claimRewards,
uint256 time
);
event UnStake(
address indexed userAddress,
address indexed unStakedtokenAddress,
uint256 unStakedAmount,
uint256 time,
uint256 stakeId
);
event ReferralEarn(
address indexed userAddress,
address indexed callerAddress,
address indexed rewardTokenAddress,
uint256 rewardAmount,
uint256 time
);
constructor(address _trustedForwarder) Admin(_msgSender()) {
poolStartTime = block.timestamp;
trustedForwarder = _trustedForwarder;
}
/**
* @notice Stake tokens to earn rewards
* @param tokenAddress Staking token address
* @param amount Amount of tokens to be staked
*/
function stake(
address referrerAddress,
address tokenAddress,
uint256 amount
) external whenNotPaused {
// checks
require(
_msgSender() != referrerAddress,
"STAKE: invalid referrer address"
);
require(
tokenDetails[tokenAddress].isExist,
"STAKE : Token is not Exist"
);
require(
userTotalStaking[_msgSender()][tokenAddress].add(amount) >=
tokenDetails[tokenAddress].userMinStake,
"STAKE : Min Amount should be within permit"
);
require(
userTotalStaking[_msgSender()][tokenAddress].add(amount) <=
tokenDetails[tokenAddress].userMaxStake,
"STAKE : Max Amount should be within permit"
);
require(
totalStaking[tokenAddress].add(amount) <=
tokenDetails[tokenAddress].totalMaxStake,
"STAKE : Maxlimit exceeds"
);
require(
poolStartTime.add(stakeDuration) > block.timestamp,
"STAKE: Staking Time Completed"
);
// Storing stake details
stakingDetails[_msgSender()].stakeId.push(
stakingDetails[_msgSender()].stakeId.length
);
stakingDetails[_msgSender()].isActive.push(true);
stakingDetails[_msgSender()].user = _msgSender();
stakingDetails[_msgSender()].referrer.push(referrerAddress);
stakingDetails[_msgSender()].tokenAddress.push(tokenAddress);
stakingDetails[_msgSender()].startTime.push(block.timestamp);
// Update total staking amount
stakingDetails[_msgSender()].stakedAmount.push(amount);
totalStaking[tokenAddress] = totalStaking[tokenAddress].add(amount);
userTotalStaking[_msgSender()][tokenAddress] = userTotalStaking[
_msgSender()
][tokenAddress].add(amount);
// Transfer tokens from user to contract
require(
IERC20(tokenAddress).transferFrom(
_msgSender(),
address(this),
amount
),
"Transfer Failed"
);
// Emit state changes
emit Stake(
_msgSender(),
(stakingDetails[_msgSender()].stakeId.length.sub(1)),
referrerAddress,
tokenAddress,
amount,
block.timestamp
);
}
/**
* @notice Claim accumulated rewards
* @param stakeId Stake ID of the user
* @param stakedAmount Staked amount of the user
*/
function claimRewards(
address userAddress,
uint256 stakeId,
uint256 stakedAmount,
uint256 totalStake
) internal {
// Local variables
uint256 interval;
uint256 endOfProfit;
interval = poolStartTime.add(stakeDuration);
// Interval calculation
if (interval > block.timestamp) endOfProfit = block.timestamp;
else endOfProfit = poolStartTime.add(stakeDuration);
interval = endOfProfit.sub(
stakingDetails[userAddress].startTime[stakeId]
);
uint256[2] memory stakeData;
stakeData[0] = (stakedAmount);
stakeData[1] = (totalStake);
// Reward calculation
if (interval >= HOURS)
_rewardCalculation(userAddress, stakeId, stakeData, interval);
}
function _rewardCalculation(
address userAddress,
uint256 stakeId,
uint256[2] memory stakingData,
uint256 interval
) internal {
uint256 rewardsEarned;
uint256 refEarned;
uint256[2] memory noOfDays;
noOfDays[1] = interval.div(HOURS);
noOfDays[0] = interval.div(DAYS);
rewardsEarned = noOfDays[1].mul(
getOneDayReward(
stakingData[0],
stakingDetails[userAddress].tokenAddress[stakeId],
stakingDetails[userAddress].tokenAddress[stakeId],
stakingData[1]
)
);
// Referrer Earning
if (stakingDetails[userAddress].referrer[stakeId] != address(0)) {
refEarned = (rewardsEarned.mul(refPercentage)).div(100 ether);
rewardsEarned = rewardsEarned.sub(refEarned);
require(
IERC20(stakingDetails[userAddress].tokenAddress[stakeId])
.transfer(
stakingDetails[userAddress].referrer[stakeId],
refEarned
) == true,
"Transfer Failed"
);
emit ReferralEarn(
stakingDetails[userAddress].referrer[stakeId],
_msgSender(),
stakingDetails[userAddress].tokenAddress[stakeId],
refEarned,
block.timestamp
);
}
// Rewards Send
sendToken(
userAddress,
stakingDetails[userAddress].tokenAddress[stakeId],
stakingDetails[userAddress].tokenAddress[stakeId],
rewardsEarned
);
uint8 i = 1;
while (i < intervalDays.length) {
if (noOfDays[0] >= intervalDays[i]) {
uint256 reductionHours = (intervalDays[i].sub(1)).mul(24);
uint256 balHours = noOfDays[1].sub(reductionHours);
address rewardToken = tokensSequenceList[
stakingDetails[userAddress].tokenAddress[stakeId]
][i];
if (
rewardToken !=
stakingDetails[userAddress].tokenAddress[stakeId] &&
tokenBlockedStatus[
stakingDetails[userAddress].tokenAddress[stakeId]
][rewardToken] ==
false
) {
rewardsEarned = balHours.mul(
getOneDayReward(
stakingData[0],
stakingDetails[userAddress].tokenAddress[stakeId],
rewardToken,
stakingData[1]
)
);
// Referrer Earning
if (
stakingDetails[userAddress].referrer[stakeId] !=
address(0)
) {
refEarned = (rewardsEarned.mul(refPercentage)).div(
100 ether
);
rewardsEarned = rewardsEarned.sub(refEarned);
require(
IERC20(rewardToken).transfer(
stakingDetails[userAddress].referrer[stakeId],
refEarned
) == true,
"Transfer Failed"
);
emit ReferralEarn(
stakingDetails[userAddress].referrer[stakeId],
_msgSender(),
stakingDetails[userAddress].tokenAddress[stakeId],
refEarned,
block.timestamp
);
}
// Rewards Send
sendToken(
userAddress,
stakingDetails[userAddress].tokenAddress[stakeId],
rewardToken,
rewardsEarned
);
}
i = i + 1;
} else {
break;
}
}
}
/**
* @notice Get rewards for one day
* @param stakedAmount Stake amount of the user
* @param stakedToken Staked token address of the user
* @param rewardToken Reward token address
* @return reward One dayh reward for the user
*/
function getOneDayReward(
uint256 stakedAmount,
address stakedToken,
address rewardToken,
uint256 totalStake
) public view returns (uint256 reward) {
uint256 lockBenefit;
if (tokenDetails[stakedToken].optionableStatus) {
stakedAmount = stakedAmount.mul(optionableBenefit);
lockBenefit = stakedAmount.mul(optionableBenefit.sub(1));
reward = (
stakedAmount.mul(
tokenDailyDistribution[stakedToken][rewardToken]
)
).div(totalStake.add(lockBenefit));
} else {
reward = (
stakedAmount.mul(
tokenDailyDistribution[stakedToken][rewardToken]
)
).div(totalStake);
}
}
/**
* @notice Get rewards for one day
* @param stakedToken Stake amount of the user
* @param tokenAddress Reward token address
* @param amount Amount to be transferred as reward
*/
function sendToken(
address userAddress,
address stakedToken,
address tokenAddress,
uint256 amount
) internal {
// Checks
if (tokenAddress != address(0)) {
require(
rewardCap[tokenAddress] >= amount,
"SEND : Insufficient Reward Balance"
);
// Transfer of rewards
rewardCap[tokenAddress] = rewardCap[tokenAddress].sub(amount);
require(
IERC20(tokenAddress).transfer(userAddress, amount),
"Transfer failed"
);
// Emit state changes
emit Claim(
userAddress,
stakedToken,
tokenAddress,
amount,
block.timestamp
);
}
}
/**
* @notice Unstake and claim rewards
* @param stakeId Stake ID of the user
*/
function unStake(address userAddress, uint256 stakeId)
external
whenNotPaused
returns (bool)
{
require(
_msgSender() == userAddress || _msgSender() == _owner,
"UNSTAKE: Invalid User Entry"
);
address stakedToken = stakingDetails[userAddress].tokenAddress[stakeId];
// lockableDays check
require(
tokenDetails[stakedToken].lockableDays <= block.timestamp,
"UNSTAKE: Token Locked"
);
// optional lock check
if (tokenDetails[stakedToken].optionableStatus)
require(
stakingDetails[userAddress].startTime[stakeId].add(
stakeDuration
) <= block.timestamp,
"UNSTAKE: Locked in optional lock"
);
// Checks
require(
stakingDetails[userAddress].stakedAmount[stakeId] > 0 ||
stakingDetails[userAddress].isActive[stakeId] == true,
"UNSTAKE : Already Claimed (or) Insufficient Staked"
);
// State updation
uint256 stakedAmount = stakingDetails[userAddress].stakedAmount[
stakeId
];
uint256 totalStaking1 = totalStaking[stakedToken];
stakingDetails[userAddress].stakedAmount[stakeId] = 0;
stakingDetails[userAddress].isActive[stakeId] = false;
// Balance check
require(
IERC20(stakingDetails[userAddress].tokenAddress[stakeId]).balanceOf(
address(this)
) >= stakedAmount,
"UNSTAKE : Insufficient Balance"
);
// Transfer staked token back to user
IERC20(stakingDetails[userAddress].tokenAddress[stakeId]).transfer(
userAddress,
stakedAmount
);
claimRewards(userAddress, stakeId, stakedAmount, totalStaking1);
// Emit state changes
emit UnStake(
userAddress,
stakingDetails[userAddress].tokenAddress[stakeId],
stakedAmount,
block.timestamp,
stakeId
);
return true;
}
function emergencyUnstake(
uint256 stakeId,
address userAddress,
address[] memory rewardtokens,
uint256[] memory amount
) external onlyOwner {
// Checks
require(
stakingDetails[userAddress].stakedAmount[stakeId] > 0 &&
stakingDetails[userAddress].isActive[stakeId] == true,
"EMERGENCY : Already Claimed (or) Insufficient Staked"
);
// Balance check
require(
IERC20(stakingDetails[userAddress].tokenAddress[stakeId]).balanceOf(
address(this)
) >= stakingDetails[userAddress].stakedAmount[stakeId],
"EMERGENCY : Insufficient Balance"
);
uint256 stakeAmount = stakingDetails[userAddress].stakedAmount[stakeId];
stakingDetails[userAddress].isActive[stakeId] = false;
stakingDetails[userAddress].stakedAmount[stakeId] = 0;
IERC20(stakingDetails[userAddress].tokenAddress[stakeId]).transfer(
userAddress,
stakeAmount
);
for (uint256 i; i < rewardtokens.length; i++) {
uint256 rewardsEarned = amount[i];
if (stakingDetails[userAddress].referrer[stakeId] != address(0)) {
uint256 refEarned = (rewardsEarned.mul(refPercentage)).div(
100 ether
);
rewardsEarned = rewardsEarned.sub(refEarned);
require(
IERC20(rewardtokens[i]).transfer(
stakingDetails[userAddress].referrer[stakeId],
refEarned
),
"EMERGENCY : Transfer Failed"
);
emit ReferralEarn(
stakingDetails[userAddress].referrer[stakeId],
userAddress,
rewardtokens[i],
refEarned,
block.timestamp
);
}
sendToken(
userAddress,
stakingDetails[userAddress].tokenAddress[stakeId],
rewardtokens[i],
rewardsEarned
);
}
// Emit state changes
emit UnStake(
userAddress,
stakingDetails[userAddress].tokenAddress[stakeId],
stakeAmount,
block.timestamp,
stakeId
);
}
/**
* @notice View staking details
* @param _user User address
*/
function viewStakingDetails(address _user)
public
view
returns (
address[] memory,
address[] memory,
bool[] memory,
uint256[] memory,
uint256[] memory,
uint256[] memory
)
{
return (
stakingDetails[_user].referrer,
stakingDetails[_user].tokenAddress,
stakingDetails[_user].isActive,
stakingDetails[_user].stakeId,
stakingDetails[_user].stakedAmount,
stakingDetails[_user].startTime
);
}
/**
* Override this function.
* This version is to keep track of BaseRelayRecipient you are using
* in your contract.
*/
function versionRecipient() external pure override returns (string memory) {
return "1";
}
function updateTrustForwarder(address _newTrustForwarder)
external
onlyOwner
{
trustedForwarder = _newTrustForwarder;
}
function pause() external onlyOwner returns (bool) {
_pause();
return true;
}
function unpause() external onlyOwner returns (bool) {
_unpause();
return true;
}
}
Read Contract
DAYS 0xc549e6b9 → uint256
HOURS 0xfbfcd241 → uint256
_admin 0x01bc45c9 → address
_owner 0xb2bdfa7b → address
getOneDayReward 0x4cd36531 → uint256
intervalDays 0xb104e006 → uint256
isTrustedForwarder 0x572b6c05 → bool
optionableBenefit 0x04a624c6 → uint256
paused 0x5c975abb → bool
poolStartTime 0x5f96dc11 → uint256
refPercentage 0xe5c46869 → uint256
rewardCap 0x7bdb8cd3 → uint256
stakeDuration 0x40f02ab6 → uint256
stakingDetails 0xa019cb4b → address
tokenBlockedStatus 0x28523eb6 → bool
tokenDailyDistribution 0x187739a4 → uint256
tokenDetails 0xdd4be683 → bool, uint8, uint256, uint256, uint256, uint256, bool
tokens 0x4f64b2be → address
tokensSequenceList 0x539cd3b4 → address
totalStaking 0xe0a79b16 → uint256
trustedForwarder 0x7da0a877 → address
userTotalStaking 0x1320da8b → uint256
versionRecipient 0x486ff0cd → string
viewStakingDetails 0x26fa24e9 → address[], address[], bool[], uint256[], uint256[], uint256[]
viewTokensCount 0x85d895ef → uint256
Write Contract 20 functions
These functions modify contract state and require a wallet transaction to execute.
addToken 0x40a16688
address tokenAddress
uint256 userMinStake
uint256 userMaxStake
uint256 totalStake
uint8 decimal
returns: bool
changeTokenBlockedStatus 0xcdd033c8
address stakedToken
address rewardToken
bool status
emergencyUnstake 0xc922e937
uint256 stakeId
address userAddress
address[] rewardtokens
uint256[] amount
lockableToken 0xd4313506
address tokenAddress
uint8 lockableStatus
uint256 lockedDays
bool optionableStatus
pause 0x8456cb59
No parameters
returns: bool
renounceOwnership 0x715018a6
No parameters
safeWithdraw 0x5058c460
address tokenAddress
uint256 amount
setDailyDistribution 0xd43c9535
address[] stakedToken
address[] rewardToken
uint256[] dailyDistribution
setRewardCap 0xf94e5c88
address[] tokenAddresses
uint256[] rewards
returns: bool
stake 0xbf6eac2f
address referrerAddress
address tokenAddress
uint256 amount
transferOwnership 0xf2fde38b
address newOwner
unStake 0xd9393814
address userAddress
uint256 stakeId
returns: bool
unpause 0x3f4ba83a
No parameters
returns: bool
updateIntervalDays 0x01193ad7
uint256[] _interval
updateOptionableBenefit 0x96591e31
uint256 benefit
updateRefPercentage 0x1d2002e7
uint256 refPer
updateSequence 0xa4f3f0e5
address stakedToken
address[] rewardTokenSequence
updateStakeDuration 0x88125f79
uint256 durationTime
updateToken 0xd768779a
address tokenAddress
uint256 userMinStake
uint256 userMaxStake
uint256 totalStake
updateTrustForwarder 0xd0cd4ee0
address _newTrustForwarder
Recent Transactions
No transactions found for this address