Address Contract Verified
Address
0x399c4a6f640f5cF5575C4d04Fec9d28DF383aC85
Balance
0 ETH
Nonce
1
Code Size
9190 bytes
Creator
0x99C85A23...D06C at tx 0x8999fa8e...5b7abd
Indexed Transactions
0 (1 on-chain, 1.0% indexed)
Contract Bytecode
9190 bytes
0x608060405234801561001057600080fd5b50600436106101a35760003560e01c806374de4ec4116100ee578063a26dbf2611610097578063b9b5d1de11610071578063b9b5d1de14610442578063d66692a71461046f578063db2e21bc14610477578063f2fde38b1461047f576101a3565b8063a26dbf2614610415578063a694fc3a1461041d578063aa5c3ab41461043a576101a3565b80638f32d59b116100c85780638f32d59b146103e65780639946e341146103ee5780639d76ea581461040d576101a3565b806374de4ec4146103b9578063750142e6146103d65780638da5cb5b146103de576101a3565b80632c4e722e1161015057806350003ca61161012a57806350003ca6146103745780635b9f0016146103a7578063715018a6146103af576101a3565b80632c4e722e146103485780633ccfd60b146103505780633f683b6a1461036c576101a3565b80630f0a3d13116101815780630f0a3d13146102a75780631bbc4b83146102f25780632986c0e514610323576101a3565b806304554443146101a857806306fdde03146101c25780630ba36dcd1461023f575b600080fd5b6101b06104b2565b60408051918252519081900360200190f35b6101ca6104b8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102045781810151838201526020016101ec565b50505050905090810190601f1680156102315780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102726004803603602081101561025557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610564565b6040805196875260208701959095528585019390935260608501919091526080840152151560a0830152519081900360c00190f35b6102ce600480360360208110156102bd57600080fd5b503567ffffffffffffffff16610602565b6040805167ffffffffffffffff909316835260208301919091528051918290030190f35b6102fa610628565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61032b610649565b6040805167ffffffffffffffff9092168252519081900360200190f35b61032b610659565b610358610675565b604080519115158252519081900360200190f35b61035861080c565b6101b06004803603602081101561038a57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610815565b6101b0610851565b6103b7610857565b005b610358600480360360208110156103cf57600080fd5b503561091f565b6101b0610b79565b6102fa610b7f565b610358610b9b565b6103b76004803603602081101561040457600080fd5b50351515610bd9565b6102fa610c9d565b6101b0610cb9565b6103586004803603602081101561043357600080fd5b5035610cbf565b6101b0610efa565b6103b76004803603604081101561045857600080fd5b5067ffffffffffffffff8135169060200135610f00565b6101b0611108565b61035861110e565b6103b76004803603602081101561049557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661129f565b600a5481565b600b805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561055c5780601f106105315761010080835404028352916020019161055c565b820191906000526020600020905b81548152906001019060200180831161053f57829003601f168201915b505050505081565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600360205260408120548190819081908190819060ff16156105f95750505073ffffffffffffffffffffffffffffffffffffffff84166000908152600160208190526040909120805491810154600282015460038301546004840154600590940154949750919550935067ffffffffffffffff169160ff165b91939550919395565b6002602052600090815260409020805460019091015467ffffffffffffffff9091169082565b600d54610100900473ffffffffffffffffffffffffffffffffffffffff1681565b60095467ffffffffffffffff1681565b60095468010000000000000000900467ffffffffffffffff1681565b600033806106ca576040805162461bcd60e51b815260206004820152600c60248201527f5a65726f20616464726573730000000000000000000000000000000000000000604482015290519081900360640190fd5b3360009081526003602052604090205460ff1661072e576040805162461bcd60e51b815260206004820152601860248201527f4e6f207374616b657320666f756e6420666f7220757365720000000000000000604482015290519081900360640190fd5b33600090815260016020526040902060020154421015610795576040805162461bcd60e51b815260206004820152601b60248201527f52657175657374696e67206265666f7265206c6f636b2074696d650000000000604482015290519081900360640190fd5b3360009081526001602052604090206005015460ff16156107fd576040805162461bcd60e51b815260206004820152601060248201527f416c72656164792070616964206f757400000000000000000000000000000000604482015290519081900360640190fd5b61080633611304565b91505090565b600d5460ff1681565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040812060020154610849908390611528565b90505b919050565b60055481565b61085f610b9b565b6108b0576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b60003380610974576040805162461bcd60e51b815260206004820152600c60248201527f5a65726f20616464726573730000000000000000000000000000000000000000604482015290519081900360640190fd5b60048054600d80547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1661010073ffffffffffffffffffffffffffffffffffffffff93841681029190911791829055604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523395810186905230602482015290518894600094939093049092169163dd62ed3e91604480820192602092909190829003018186803b158015610a2c57600080fd5b505afa158015610a40573d6000803e3d6000fd5b505050506040513d6020811015610a5657600080fd5b5051905080821115610a995760405162461bcd60e51b815260040180806020018281038252602181526020018061231d6021913960400191505060405180910390fd5b60008611610aee576040805162461bcd60e51b815260206004820152601760248201527f526577617264206d75737420626520706f736974697665000000000000000000604482015290519081900360640190fd5b600854610b01908763ffffffff61173e16565b600855600654610b17908763ffffffff61173e16565b600655610b24338761179f565b610b315760009450610b70565b6040805187815242602082015281517f40df43107e8b4d467127964bd3c966687c0a6a39aaede970755397fd09535e98929181900390910190a1600194505b50505050919050565b60085481565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6000805473ffffffffffffffffffffffffffffffffffffffff16610bbd6117ac565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b610be1610b9b565b610c32576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215159081179091556040805191825242602083015280517f36e3f34a0ee7e675c6e4fb54887d109037e69fb0e40bffc3b86a4887960a019b9281900390910190a150565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b600c5481565b60003380610d14576040805162461bcd60e51b815260206004820152600c60248201527f5a65726f20616464726573730000000000000000000000000000000000000000604482015290519081900360640190fd5b60048054600d80547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1661010073ffffffffffffffffffffffffffffffffffffffff93841681029190911791829055604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523395810186905230602482015290518894600094939093049092169163dd62ed3e91604480820192602092909190829003018186803b158015610dcc57600080fd5b505afa158015610de0573d6000803e3d6000fd5b505050506040513d6020811015610df657600080fd5b5051905080821115610e395760405162461bcd60e51b815260040180806020018281038252602181526020018061231d6021913960400191505060405180910390fd5b60008611610e8e576040805162461bcd60e51b815260206004820152601460248201527f43616e2774207374616b65203020616d6f756e74000000000000000000000000604482015290519081900360640190fd5b600d5460ff1615610ee6576040805162461bcd60e51b815260206004820152600e60248201527f5374616b696e6720706175736564000000000000000000000000000000000000604482015290519081900360640190fd5b610ef033876117b0565b9695505050505050565b60065481565b610f08610b9b565b610f59576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b67ffffffffffffffff8216610fb5576040805162461bcd60e51b815260206004820152601260248201527f5a65726f20696e74657265737420726174650000000000000000000000000000604482015290519081900360640190fd5b80611007576040805162461bcd60e51b815260206004820152601260248201527f5a65726f206c6f636b206475726174696f6e0000000000000000000000000000604482015290519081900360640190fd5b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000007fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091166801000000000000000067ffffffffffffffff8681169182029290921783811660019184168201841617808655604080518082018252848152426020808301828152948816600090815260028252849020925183549099169888169890981782559251930192909255600a8790559454815193168352928201528082018490526060810192909252517fcef8b5fd0fe8d4a25244c395e72076a1d6a1b552c7116e90af6f8b2d7f61aeb0916080908290030190a15050565b60075481565b60003380611163576040805162461bcd60e51b815260206004820152600c60248201527f5a65726f20616464726573730000000000000000000000000000000000000000604482015290519081900360640190fd5b3360009081526003602052604090205460ff166111c7576040805162461bcd60e51b815260206004820152601860248201527f4e6f207374616b657320666f756e6420666f7220757365720000000000000000604482015290519081900360640190fd5b3360009081526001602052604090206002015442101561122e576040805162461bcd60e51b815260206004820152601b60248201527f52657175657374696e67206265666f7265206c6f636b2074696d650000000000604482015290519081900360640190fd5b3360009081526001602052604090206005015460ff1615611296576040805162461bcd60e51b815260206004820152601060248201527f416c72656164792070616964206f757400000000000000000000000000000000604482015290519081900360640190fd5b61080633611c2b565b6112a7610b9b565b6112f8576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b61130181611da5565b50565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040812060020154819061133a908490611528565b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602052604090206004015490915061137790829063ffffffff61173e16565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260016020526040902054600654919250908211156113f8576040805162461bcd60e51b815260206004820152601260248201527f4e6f7420656e6f75676820726577617264730000000000000000000000000000604482015290519081900360640190fd5b60055461140b908263ffffffff611e8416565b600555600654611421908363ffffffff611e8416565b60065573ffffffffffffffffffffffffffffffffffffffff8416600090815260016020818152604080842060050180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00908116851790915560039092529092208054909216909155600c5461149c9163ffffffff611e8416565b600c556114b8846114b3838563ffffffff61173e16565b611ee1565b1561151e576004546040805183815260208101859052815173ffffffffffffffffffffffffffffffffffffffff8089169416927f85ab59351da11b79336de7647172267c33bf533ee87d9d292441c2672177159b928290030190a360019250505061084c565b5060009392505050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081205460ff1661155d57506000611738565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600160208190526040822080549181015460038201546002909201549293909267ffffffffffffffff90921691819081906115ba908663ffffffff611e8416565b9050835b60095467ffffffffffffffff90811690821610156116cd57600181810167ffffffffffffffff1660009081526002602052604090200154891015611601576116cd565b600181810167ffffffffffffffff166000908152600260205260409020015461162a9087611e84565b935061168c6116418361271063ffffffff611f4b16565b67ffffffffffffffff808416600090815260026020526040902054611680918891611674918d911663ffffffff611f4b16565b9063ffffffff611f4b16565b9063ffffffff611fa416565b925061169e878463ffffffff61173e16565b600191820167ffffffffffffffff811660009081526002602052604090208301549198509096509401936115be565b5087851015611730576116e6888663ffffffff611e8416565b925061172d6116fd8261271063ffffffff611f4b16565b67ffffffffffffffff8087166000908152600260205260409020546116809116611674878b63ffffffff611f4b16565b91505b509450505050505b92915050565b600082820183811015611798576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600061179883308461200e565b3390565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081205460ff1661195a5773ffffffffffffffffffffffffffffffffffffffff831660009081526003602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055815160c0810183528481524291810191909152600a54909182019061186d9061186090610e1063ffffffff611f4b16565b429063ffffffff61173e16565b815260095467ffffffffffffffff90811660208084019190915260006040808501829052606094850182905273ffffffffffffffffffffffffffffffffffffffff891682526001808452918190208651815592860151838301558501516002830155928401516003820180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001691909316179091556080830151600482015560a090920151600590920180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001692151592909217909155600c546119529161173e565b600c55611b49565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604090206002015442106119c05760405162461bcd60e51b815260040180806020018281038252602d815260200180612385602d913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152600160205260408120546119f6908463ffffffff61173e16565b73ffffffffffffffffffffffffffffffffffffffff851660009081526001602052604081206004015491925090611a3d90611a318742611528565b9063ffffffff61173e16565b90506040518060c00160405280838152602001428152602001611a70611860610e10600a54611f4b90919063ffffffff16565b815260095467ffffffffffffffff9081166020808401919091526040808401959095526000606093840181905273ffffffffffffffffffffffffffffffffffffffff8a168152600180835290869020855181559185015190820155938301516002850155908201516003840180547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016919092161790556080810151600483015560a00151600590910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055505b600554611b5c908363ffffffff61173e16565b600555600754611b72908363ffffffff61173e16565b600755611b7f838361179f565b611bd0576040805162461bcd60e51b815260206004820152600e60248201527f5061796d656e74206661696c6564000000000000000000000000000000000000604482015290519081900360640190fd5b60045460408051848152905173ffffffffffffffffffffffffffffffffffffffff8087169316917f5dac0c1b1112564a045ba943c9d50270893e8e826c49be8e7073adc713ab7bd7919081900360200190a350600192915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040812054600554611c64908263ffffffff611e8416565b600590815573ffffffffffffffffffffffffffffffffffffffff8416600090815260016020818152604080842090940180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090811684179091556003909152929091208054909216909155600c54611ce29163ffffffff611e8416565b600c556000611cf18483611ee1565b905080611d45576040805162461bcd60e51b815260206004820152600c60248201527f4572726f7220706179696e670000000000000000000000000000000000000000604482015290519081900360640190fd5b6004546040805184815260006020820152815173ffffffffffffffffffffffffffffffffffffffff8089169416927f85ab59351da11b79336de7647172267c33bf533ee87d9d292441c2672177159b928290030190a35060019392505050565b73ffffffffffffffffffffffffffffffffffffffff8116611df75760405162461bcd60e51b815260040180806020018281038252602681526020018061233e6026913960400191505060405180910390fd5b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600082821115611edb576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600454600d80547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1661010073ffffffffffffffffffffffffffffffffffffffff93841681029190911791829055600092611f42929190910416848461219f565b50600192915050565b600082611f5a57506000611738565b82820282848281611f6757fe5b04146117985760405162461bcd60e51b81526004018080602001828103825260218152602001806123646021913960400191505060405180910390fd5b6000808211611ffa576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b600082848161200557fe5b04949350505050565b60048054600d80547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1661010073ffffffffffffffffffffffffffffffffffffffff93841681029190911791829055604080517fdd62ed3e00000000000000000000000000000000000000000000000000000000815288851695810195909552306024860152516000948894879487949004169163dd62ed3e91604480820192602092909190829003018186803b1580156120c857600080fd5b505afa1580156120dc573d6000803e3d6000fd5b505050506040513d60208110156120f257600080fd5b50519050808211156121355760405162461bcd60e51b815260040180806020018281038252602181526020018061231d6021913960400191505060405180910390fd5b600454600d80547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1661010073ffffffffffffffffffffffffffffffffffffffff9384168102919091179182905561219292910416888888612260565b5060019695505050505050565b8273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561222657600080fd5b505af115801561223a573d6000803e3d6000fd5b505050506040513d602081101561225057600080fd5b505161225b57600080fd5b505050565b604080517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301528481166024830152604482018490529151918616916323b872dd916064808201926020929091908290030181600087803b1580156122e157600080fd5b505af11580156122f5573d6000803e3d6000fd5b505050506040513d602081101561230b57600080fd5b505161231657600080fd5b5050505056fe4d616b65207375726520746f2061646420656e6f75676820616c6c6f77616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774c6f636b20657870697265642c20706c6561736520776974686472617720616e64207374616b6520616761696ea265627a7a723158204c4e08ed313ea3a7e03906dd91104211cd48f40994a857694e308176dae6f0d264736f6c63430005100032
Verified Source Code Full Match
Compiler: v0.5.16+commit.9c3226ce
EVM: istanbul
Optimization: Yes (20000 runs)
Locking.sol 555 lines
pragma solidity 0.5.16;
/**
* @dev Interface of the ERC20 standard as defined in the EIP. Does not include
* the optional functions; to access them see `ERC20Detailed`.
*/
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount)
external
returns (bool);
function allowance(address owner, address spender)
external
view
returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
// File: openzeppelin-solidity/contracts/math/SafeMath.sol
pragma solidity 0.5.16;
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, "SafeMath: division by zero");
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0, "SafeMath: modulo by zero");
return a % b;
}
}
pragma solidity 0.5.16;
contract Context {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
constructor() internal {}
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode
return msg.data;
}
}
// File: @openzeppelin/contracts/ownership/Ownable.sol
pragma solidity 0.5.16;
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
constructor() internal {
_owner = _msgSender();
emit OwnershipTransferred(address(0), _owner);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(isOwner(), "Ownable: caller is not the owner");
_;
}
function isOwner() public view returns (bool) {
return _msgSender() == _owner;
}
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
library SafeERC20 {
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
require(token.transfer(to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
require(token.transferFrom(from, to, value));
}
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
require(token.approve(spender, value));
}
}
pragma solidity 0.5.16;
contract IDOLocking is Ownable {
using SafeMath for uint256;
using SafeERC20 for IERC20;
/**
* @dev Structs to store user staking data.
*/
struct Deposits {
uint256 depositAmount;
uint256 depositTime;
uint256 endTime;
uint64 userIndex;
uint256 rewards;
bool paid;
}
/**
* @dev Structs to store interest rate change.
*/
struct Rates {
uint64 newInterestRate;
uint256 timeStamp;
}
mapping(address => Deposits) private deposits;
mapping(uint64 => Rates) public rates;
mapping(address => bool) private hasStaked;
address public tokenAddress;
uint256 public stakedBalance;
uint256 public rewardBalance;
uint256 public stakedTotal;
uint256 public totalReward;
uint64 public index;
uint64 public rate;
uint256 public lockDuration;
string public name;
uint256 public totalParticipants;
bool public isStopped;
IERC20 public ERC20Interface;
/**
* @dev Emitted when user stakes 'stakedAmount' value of tokens
*/
event Staked(
address indexed token,
address indexed staker_,
uint256 stakedAmount_
);
/**
* @dev Emitted when user withdraws his stakings
*/
event PaidOut(
address indexed token,
address indexed staker_,
uint256 amount_,
uint256 reward_
);
event RateAndLockduration(
uint64 index,
uint64 newRate,
uint256 lockDuration,
uint256 time
);
event RewardsAdded(uint256 rewards, uint256 time);
event StakingStopped(bool status, uint256 time);
/**
* @param
* name_ name of the contract
* tokenAddress_ contract address of the token
* rate_ rate multiplied by 100
* lockduration_ duration in days
*/
constructor(
string memory name_,
address tokenAddress_,
uint64 rate_,
uint256 lockDuration_
) public Ownable() {
name = name_;
require(tokenAddress_ != address(0), "Zero token address");
tokenAddress = tokenAddress_;
lockDuration = lockDuration_;
require(rate_ != 0, "Zero interest rate");
rate = rate_;
rates[index] = Rates(rate, block.timestamp);
}
/**
* Requirements:
* `rate_` New effective interest rate multiplied by 100
* @dev to set interest rates
* `lockduration_' lock days
* @dev to set lock duration days
*/
function setRateAndLockduration(uint64 rate_, uint256 lockduration_)
external
onlyOwner
{
require(rate_ != 0, "Zero interest rate");
require(lockduration_ != 0, "Zero lock duration");
rate = rate_;
index++;
rates[index] = Rates(rate_, block.timestamp);
lockDuration = lockduration_;
emit RateAndLockduration(index, rate_, lockduration_, block.timestamp);
}
function changeStakingStatus(bool _status) external onlyOwner {
isStopped = _status;
emit StakingStopped(_status, block.timestamp);
}
/**
* Requirements:
* `rewardAmount` rewards to be added to the staking contract
* @dev to add rewards to the staking contract
* once the allowance is given to this contract for 'rewardAmount' by the user
*/
function addReward(uint256 rewardAmount)
external
_realAddress(msg.sender)
_hasAllowance(msg.sender, rewardAmount)
returns (bool)
{
require(rewardAmount > 0, "Reward must be positive");
totalReward = totalReward.add(rewardAmount);
rewardBalance = rewardBalance.add(rewardAmount);
if (!_payMe(msg.sender, rewardAmount)) {
return false;
}
emit RewardsAdded(rewardAmount, block.timestamp);
return true;
}
/**
* Requirements:
* `user` User wallet address
* @dev returns user staking data
*/
function userDeposits(address user)
external
view
returns (
uint256,
uint256,
uint256,
uint256,
uint256,
bool
)
{
if (hasStaked[user]) {
return (
deposits[user].depositAmount,
deposits[user].depositTime,
deposits[user].endTime,
deposits[user].userIndex,
deposits[user].rewards,
deposits[user].paid
);
}
}
/**
* Requirements:
* `amount` Amount to be staked
/**
* @dev to stake 'amount' value of tokens
* once the user has given allowance to the staking contract
*/
function stake(uint256 amount)
external
_realAddress(msg.sender)
_hasAllowance(msg.sender, amount)
returns (bool)
{
require(amount > 0, "Can't stake 0 amount");
require(!isStopped, "Staking paused");
return (_stake(msg.sender, amount));
}
function _stake(address from, uint256 amount) private returns (bool) {
if (!hasStaked[from]) {
hasStaked[from] = true;
deposits[from] = Deposits(
amount,
block.timestamp,
block.timestamp.add((lockDuration.mul(3600))),
index,
0,
false
);
totalParticipants = totalParticipants.add(1);
} else {
require(
block.timestamp < deposits[from].endTime,
"Lock expired, please withdraw and stake again"
);
uint256 newAmount = deposits[from].depositAmount.add(amount);
uint256 rewards = _calculate(from, block.timestamp).add(
deposits[from].rewards
);
deposits[from] = Deposits(
newAmount,
block.timestamp,
block.timestamp.add((lockDuration.mul(3600))),
index,
rewards,
false
);
}
stakedBalance = stakedBalance.add(amount);
stakedTotal = stakedTotal.add(amount);
require(_payMe(from, amount), "Payment failed");
emit Staked(tokenAddress, from, amount);
return true;
}
/**
* @dev to withdraw user stakings after the lock period ends.
*/
function withdraw() external _realAddress(msg.sender) returns (bool) {
require(hasStaked[msg.sender], "No stakes found for user");
require(
block.timestamp >= deposits[msg.sender].endTime,
"Requesting before lock time"
);
require(!deposits[msg.sender].paid, "Already paid out");
return (_withdraw(msg.sender));
}
function _withdraw(address from) private returns (bool) {
uint256 reward = _calculate(from, deposits[from].endTime);
reward = reward.add(deposits[from].rewards);
uint256 amount = deposits[from].depositAmount;
require(reward <= rewardBalance, "Not enough rewards");
stakedBalance = stakedBalance.sub(amount);
rewardBalance = rewardBalance.sub(reward);
deposits[from].paid = true;
hasStaked[from] = false;
totalParticipants = totalParticipants.sub(1);
if (_payDirect(from, amount.add(reward))) {
emit PaidOut(tokenAddress, from, amount, reward);
return true;
}
return false;
}
function emergencyWithdraw()
external
_realAddress(msg.sender)
returns (bool)
{
require(hasStaked[msg.sender], "No stakes found for user");
require(
block.timestamp >= deposits[msg.sender].endTime,
"Requesting before lock time"
);
require(!deposits[msg.sender].paid, "Already paid out");
return (_emergencyWithdraw(msg.sender));
}
function _emergencyWithdraw(address from) private returns (bool) {
uint256 amount = deposits[from].depositAmount;
stakedBalance = stakedBalance.sub(amount);
deposits[from].paid = true;
hasStaked[from] = false; //Check-Effects-Interactions pattern
totalParticipants = totalParticipants.sub(1);
bool principalPaid = _payDirect(from, amount);
require(principalPaid, "Error paying");
emit PaidOut(tokenAddress, from, amount, 0);
return true;
}
/**
* Requirements:
* `from` User wallet address
* @dev to calculate the rewards based on user staked 'amount'
* 'userIndex' - the index of the interest rate at the time of user stake.
* 'depositTime' - time of staking
*/
function calculate(address from) external view returns (uint256) {
return _calculate(from, deposits[from].endTime);
}
function _calculate(address from, uint256 endTime)
private
view
returns (uint256)
{
if (!hasStaked[from]) return 0;
(uint256 amount, uint256 depositTime, uint64 userIndex) = (
deposits[from].depositAmount,
deposits[from].depositTime,
deposits[from].userIndex
);
uint256 time;
uint256 interest;
uint256 _lockduration = deposits[from].endTime.sub(depositTime);
for (uint64 i = userIndex; i < index; i++) {
//loop runs till the latest index/interest rate change
if (endTime < rates[i + 1].timeStamp) {
//if the change occurs after the endTime loop breaks
break;
} else {
time = rates[i + 1].timeStamp.sub(depositTime);
interest = amount.mul(rates[i].newInterestRate).mul(time).div(
_lockduration.mul(10000)
);
amount = amount.add(interest);
depositTime = rates[i + 1].timeStamp;
userIndex++;
}
}
if (depositTime < endTime) {
//final calculation for the remaining time period
time = endTime.sub(depositTime);
interest = time
.mul(amount)
.mul(rates[userIndex].newInterestRate)
.div(_lockduration.mul(10000));
}
return (interest);
}
function _payMe(address payer, uint256 amount) private returns (bool) {
return _payTo(payer, address(this), amount);
}
function _payTo(
address allower,
address receiver,
uint256 amount
) private _hasAllowance(allower, amount) returns (bool) {
ERC20Interface = IERC20(tokenAddress);
ERC20Interface.safeTransferFrom(allower, receiver, amount);
return true;
}
function _payDirect(address to, uint256 amount) private returns (bool) {
ERC20Interface = IERC20(tokenAddress);
ERC20Interface.safeTransfer(to, amount);
return true;
}
modifier _realAddress(address addr) {
require(addr != address(0), "Zero address");
_;
}
modifier _hasAllowance(address allower, uint256 amount) {
// Make sure the allower has provided the right allowance.
ERC20Interface = IERC20(tokenAddress);
uint256 ourAllowance = ERC20Interface.allowance(allower, address(this));
require(amount <= ourAllowance, "Make sure to add enough allowance");
_;
}
}
Read Contract
ERC20Interface 0x1bbc4b83 → address
calculate 0x50003ca6 → uint256
index 0x2986c0e5 → uint64
isOwner 0x8f32d59b → bool
isStopped 0x3f683b6a → bool
lockDuration 0x04554443 → uint256
name 0x06fdde03 → string
owner 0x8da5cb5b → address
rate 0x2c4e722e → uint64
rates 0x0f0a3d13 → uint64, uint256
rewardBalance 0xaa5c3ab4 → uint256
stakedBalance 0x5b9f0016 → uint256
stakedTotal 0xd66692a7 → uint256
tokenAddress 0x9d76ea58 → address
totalParticipants 0xa26dbf26 → uint256
totalReward 0x750142e6 → uint256
userDeposits 0x0ba36dcd → uint256, uint256, uint256, uint256, uint256, bool
Write Contract 8 functions
These functions modify contract state and require a wallet transaction to execute.
addReward 0x74de4ec4
uint256 rewardAmount
returns: bool
changeStakingStatus 0x9946e341
bool _status
emergencyWithdraw 0xdb2e21bc
No parameters
returns: bool
renounceOwnership 0x715018a6
No parameters
setRateAndLockduration 0xb9b5d1de
uint64 rate_
uint256 lockduration_
stake 0xa694fc3a
uint256 amount
returns: bool
transferOwnership 0xf2fde38b
address newOwner
withdraw 0x3ccfd60b
No parameters
returns: bool
Recent Transactions
This address has 1 on-chain transactions, but only 1.0% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →