Contract Address Details

0xbCa51ae3896f4033fb7B467BD3ab4A4ff27f3a3E

MultiRewards Last Balance Update: Block #13585896
Created by 0xd418–485ec6 at 0xe22a–329514

Balance

0 Fuse

(@ /Fuse)

Fetching tokens...

Contract name:
MultiRewards




Optimization enabled
true
Compiler version
v0.5.17+commit.d19bba13




Optimization runs
200
EVM Version
default

Constructor Arguments

000000000000000000000000d418c5d0c4a3d87a6c555b7aa41f13ef87485ec600000000000000000000000075e24462108e49b71278c93b49b35a5837c0547c

Arg [0] (address) : 0xd418c5d0c4a3d87a6c555b7aa41f13ef87485ec6
Arg [1] (address) : 0x75e24462108e49b71278c93b49b35a5837c0547c

              

Contract source code

/**
* Submitted for verification at blockscout.com on 2021-08-12 10:56:47.931421Z
*/
pragma solidity 0.5.17;
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* This test is non-exhaustive, and there may be false-negatives: during the
* execution of a contract's constructor, its address will be reported as
* not containing a contract.
*
* > It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*/
function isContract(address account) internal view returns (bool) {
// This method relies in extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
}
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.
*
* > 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);
}
library Math {
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow, so we distribute
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
}
}
contract Owned {
address public owner;
address public nominatedOwner;
constructor(address _owner) public {
require(_owner != address(0), "Owner address cannot be 0");
owner = _owner;
emit OwnerChanged(address(0), _owner);
}
function nominateNewOwner(address _owner) external onlyOwner {
nominatedOwner = _owner;
emit OwnerNominated(_owner);
}
function acceptOwnership() external {
require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership");
emit OwnerChanged(owner, nominatedOwner);
owner = nominatedOwner;
nominatedOwner = address(0);
}
modifier onlyOwner {
_onlyOwner();
_;
}
function _onlyOwner() private view {
require(msg.sender == owner, "Only the contract owner may perform this action");
}
event OwnerNominated(address newOwner);
event OwnerChanged(address oldOwner, address newOwner);
}
contract Pausable is Owned {
uint public lastPauseTime;
bool public paused;
constructor() internal {
// This contract is abstract, and thus cannot be instantiated directly
require(owner != address(0), "Owner must be set");
// Paused will be false, and lastPauseTime will be 0 upon initialisation
}
/**
* @notice Change the paused state of the contract
* @dev Only the contract owner may call this.
*/
function setPaused(bool _paused) external onlyOwner {
// Ensure we're actually changing the state before we do anything
if (_paused == paused) {
return;
}
// Set our paused state.
paused = _paused;
// If applicable, set the last pause time.
if (paused) {
lastPauseTime = now;
}
// Let everyone know that our pause state has changed.
emit PauseChanged(paused);
}
event PauseChanged(bool isPaused);
modifier notPaused {
require(!paused, "This action cannot be performed while the contract is paused");
_;
}
}
contract ReentrancyGuard {
/// @dev counter to allow mutex lock with only one SSTORE operation
uint256 private _guardCounter;
constructor () internal {
// The counter starts at one to prevent changing it from zero to a non-zero
// value, which is a more expensive operation.
_guardCounter = 1;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_guardCounter += 1;
uint256 localCounter = _guardCounter;
_;
require(localCounter == _guardCounter, "ReentrancyGuard: reentrant call");
}
}
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
// solhint-disable-next-line max-line-length
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves.
// A Solidity high level call has three parts:
// 1. The target address is checked to verify it contains contract code
// 2. The call itself is made, and success asserted
// 3. The return value is decoded, which in turn checks the size of the returned data.
// solhint-disable-next-line max-line-length
require(address(token).isContract(), "SafeERC20: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = address(token).call(data);
require(success, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
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) {
require(b <= a, "SafeMath: subtraction overflow");
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-solidity/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) {
// 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;
}
/**
* @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) {
require(b != 0, "SafeMath: modulo by zero");
return a % b;
}
}
contract MultiRewards is ReentrancyGuard, Pausable {
using SafeMath for uint256;
using SafeERC20 for IERC20;
/* ========== STATE VARIABLES ========== */
struct Reward {
address rewardsDistributor;
uint256 rewardsDuration;
uint256 periodFinish;
uint256 rewardRate;
uint256 lastUpdateTime;
uint256 rewardPerTokenStored;
}
IERC20 public stakingToken;
mapping(address => Reward) public rewardData;
address[] public rewardTokens;
// user -> reward token -> amount
mapping(address => mapping(address => uint256)) public userRewardPerTokenPaid;
mapping(address => mapping(address => uint256)) public rewards;
uint256 private _totalSupply;
mapping(address => uint256) private _balances;
/* ========== CONSTRUCTOR ========== */
constructor(
address _owner,
address _stakingToken
) public Owned(_owner) {
stakingToken = IERC20(_stakingToken);
}
function addReward(
address _rewardsToken,
address _rewardsDistributor,
uint256 _rewardsDuration
)
public
onlyOwner
{
require(rewardData[_rewardsToken].rewardsDuration == 0);
rewardTokens.push(_rewardsToken);
rewardData[_rewardsToken].rewardsDistributor = _rewardsDistributor;
rewardData[_rewardsToken].rewardsDuration = _rewardsDuration;
}
/* ========== VIEWS ========== */
function totalSupply() external view returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) external view returns (uint256) {
return _balances[account];
}
function lastTimeRewardApplicable(address _rewardsToken) public view returns (uint256) {
return Math.min(block.timestamp, rewardData[_rewardsToken].periodFinish);
}
function rewardPerToken(address _rewardsToken) public view returns (uint256) {
if (_totalSupply == 0) {
return rewardData[_rewardsToken].rewardPerTokenStored;
}
return
rewardData[_rewardsToken].rewardPerTokenStored.add(
lastTimeRewardApplicable(_rewardsToken).sub(rewardData[_rewardsToken].lastUpdateTime).mul(rewardData[_rewardsToken].rewardRate).mul(1e18).div(_totalSupply)
);
}
function earned(address account, address _rewardsToken) public view returns (uint256) {
return _balances[account].mul(rewardPerToken(_rewardsToken).sub(userRewardPerTokenPaid[account][_rewardsToken])).div(1e18).add(rewards[account][_rewardsToken]);
}
function getRewardForDuration(address _rewardsToken) external view returns (uint256) {
return rewardData[_rewardsToken].rewardRate.mul(rewardData[_rewardsToken].rewardsDuration);
}
/* ========== MUTATIVE FUNCTIONS ========== */
function setRewardsDistributor(address _rewardsToken, address _rewardsDistributor) external onlyOwner {
rewardData[_rewardsToken].rewardsDistributor = _rewardsDistributor;
}
function stake(uint256 amount) external nonReentrant notPaused updateReward(msg.sender) {
require(amount > 0, "Cannot stake 0");
_totalSupply = _totalSupply.add(amount);
_balances[msg.sender] = _balances[msg.sender].add(amount);
stakingToken.safeTransferFrom(msg.sender, address(this), amount);
emit Staked(msg.sender, amount);
}
function withdraw(uint256 amount) public nonReentrant updateReward(msg.sender) {
require(amount > 0, "Cannot withdraw 0");
_totalSupply = _totalSupply.sub(amount);
_balances[msg.sender] = _balances[msg.sender].sub(amount);
stakingToken.safeTransfer(msg.sender, amount);
emit Withdrawn(msg.sender, amount);
}
function getReward() public nonReentrant updateReward(msg.sender) {
for (uint i; i < rewardTokens.length; i++) {
address _rewardsToken = rewardTokens[i];
uint256 reward = rewards[msg.sender][_rewardsToken];
if (reward > 0) {
rewards[msg.sender][_rewardsToken] = 0;
IERC20(_rewardsToken).safeTransfer(msg.sender, reward);
emit RewardPaid(msg.sender, _rewardsToken, reward);
}
}
}
function exit() external {
withdraw(_balances[msg.sender]);
getReward();
}
/* ========== RESTRICTED FUNCTIONS ========== */
function notifyRewardAmount(address _rewardsToken, uint256 reward) external updateReward(address(0)) {
require(rewardData[_rewardsToken].rewardsDistributor == msg.sender);
// handle the transfer of reward tokens via `transferFrom` to reduce the number
// of transactions required and ensure correctness of the reward amount
IERC20(_rewardsToken).safeTransferFrom(msg.sender, address(this), reward);
if (block.timestamp >= rewardData[_rewardsToken].periodFinish) {
rewardData[_rewardsToken].rewardRate = reward.div(rewardData[_rewardsToken].rewardsDuration);
} else {
uint256 remaining = rewardData[_rewardsToken].periodFinish.sub(block.timestamp);
uint256 leftover = remaining.mul(rewardData[_rewardsToken].rewardRate);
rewardData[_rewardsToken].rewardRate = reward.add(leftover).div(rewardData[_rewardsToken].rewardsDuration);
}
rewardData[_rewardsToken].lastUpdateTime = block.timestamp;
rewardData[_rewardsToken].periodFinish = block.timestamp.add(rewardData[_rewardsToken].rewardsDuration);
emit RewardAdded(reward);
}
// Added to support recovering LP Rewards from other systems such as BAL to be distributed to holders
function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner {
require(tokenAddress != address(stakingToken), "Cannot withdraw staking token");
require(rewardData[tokenAddress].lastUpdateTime == 0, "Cannot withdraw reward token");
IERC20(tokenAddress).safeTransfer(owner, tokenAmount);
emit Recovered(tokenAddress, tokenAmount);
}
function setRewardsDuration(address _rewardsToken, uint256 _rewardsDuration) external {
require(
block.timestamp > rewardData[_rewardsToken].periodFinish,
"Reward period still active"
);
require(rewardData[_rewardsToken].rewardsDistributor == msg.sender);
require(_rewardsDuration > 0, "Reward duration must be non-zero");
rewardData[_rewardsToken].rewardsDuration = _rewardsDuration;
emit RewardsDurationUpdated(_rewardsToken, rewardData[_rewardsToken].rewardsDuration);
}
/* ========== MODIFIERS ========== */
modifier updateReward(address account) {
for (uint i; i < rewardTokens.length; i++) {
address token = rewardTokens[i];
rewardData[token].rewardPerTokenStored = rewardPerToken(token);
rewardData[token].lastUpdateTime = lastTimeRewardApplicable(token);
if (account != address(0)) {
rewards[account][token] = earned(account, token);
userRewardPerTokenPaid[account][token] = rewardData[token].rewardPerTokenStored;
}
}
_;
}
/* ========== EVENTS ========== */
event RewardAdded(uint256 reward);
event Staked(address indexed user, uint256 amount);
event Withdrawn(address indexed user, uint256 amount);
event RewardPaid(address indexed user, address indexed rewardsToken, uint256 reward);
event RewardsDurationUpdated(address token, uint256 newDuration);
event Recovered(address token, uint256 amount);
}

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","payable":false,"inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"_stakingToken","internalType":"address"}]},{"type":"event","name":"OwnerChanged","inputs":[{"type":"address","name":"oldOwner","internalType":"address","indexed":false},{"type":"address","name":"newOwner","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"OwnerNominated","inputs":[{"type":"address","name":"newOwner","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"PauseChanged","inputs":[{"type":"bool","name":"isPaused","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"Recovered","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RewardAdded","inputs":[{"type":"uint256","name":"reward","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RewardPaid","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"address","name":"rewardsToken","internalType":"address","indexed":true},{"type":"uint256","name":"reward","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RewardsDurationUpdated","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"newDuration","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Staked","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Withdrawn","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"acceptOwnership","inputs":[],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"addReward","inputs":[{"type":"address","name":"_rewardsToken","internalType":"address"},{"type":"address","name":"_rewardsDistributor","internalType":"address"},{"type":"uint256","name":"_rewardsDuration","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"earned","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"address","name":"_rewardsToken","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"exit","inputs":[],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"getReward","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getRewardForDuration","inputs":[{"type":"address","name":"_rewardsToken","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastPauseTime","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastTimeRewardApplicable","inputs":[{"type":"address","name":"_rewardsToken","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"nominateNewOwner","inputs":[{"type":"address","name":"_owner","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"nominatedOwner","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"notifyRewardAmount","inputs":[{"type":"address","name":"_rewardsToken","internalType":"address"},{"type":"uint256","name":"reward","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"recoverERC20","inputs":[{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"uint256","name":"tokenAmount","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"rewardsDistributor","internalType":"address"},{"type":"uint256","name":"rewardsDuration","internalType":"uint256"},{"type":"uint256","name":"periodFinish","internalType":"uint256"},{"type":"uint256","name":"rewardRate","internalType":"uint256"},{"type":"uint256","name":"lastUpdateTime","internalType":"uint256"},{"type":"uint256","name":"rewardPerTokenStored","internalType":"uint256"}],"name":"rewardData","inputs":[{"type":"address","name":"","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardPerToken","inputs":[{"type":"address","name":"_rewardsToken","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"rewardTokens","inputs":[{"type":"uint256","name":"","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewards","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setPaused","inputs":[{"type":"bool","name":"_paused","internalType":"bool"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setRewardsDistributor","inputs":[{"type":"address","name":"_rewardsToken","internalType":"address"},{"type":"address","name":"_rewardsDistributor","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setRewardsDuration","inputs":[{"type":"address","name":"_rewardsToken","internalType":"address"},{"type":"uint256","name":"_rewardsDuration","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"stake","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"stakingToken","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"userRewardPerTokenPaid","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}],"constant":false}]
            

Contract Byte Code

0x608060405234801561001057600080fd5b50600436106101a95760003560e01c806370a08231116100f9578063a694fc3a11610097578063d0ed26ae11610071578063d0ed26ae146104b1578063e70b9e27146104e7578063e9fad8ee14610515578063f12297771461051d576101a9565b8063a694fc3a14610442578063b66503cf1461045f578063bcd110141461048b576101a9565b80637bb7bed1116100d35780637bb7bed1146103e95780638980f11f146104065780638da5cb5b1461043257806391b4ded91461043a576101a9565b806370a08231146103b357806372f702f3146103d957806379ba5097146103e1576101a9565b80633d18b9121161016657806353a47bb71161014057806353a47bb71461031f5780635c975abb14610343578063638634ee1461035f5780637035ab9814610385576101a9565b80633d18b912146102865780633f695b451461028e57806348e5d9f8146102bc576101a9565b80631627540c146101ae57806316c38b3c146101d657806318160ddd146101f5578063211dc32d1461020f5780632378bea61461023d5780632e1a7d4d14610269575b600080fd5b6101d4600480360360208110156101c457600080fd5b50356001600160a01b0316610543565b005b6101d4600480360360208110156101ec57600080fd5b5035151561059f565b6101fd610619565b60408051918252519081900360200190f35b6101fd6004803603604081101561022557600080fd5b506001600160a01b038135811691602001351661061f565b6101d46004803603604081101561025357600080fd5b506001600160a01b0381351690602001356106d2565b6101d46004803603602081101561027f57600080fd5b5035610818565b6101d4610a52565b6101d4600480360360408110156102a457600080fd5b506001600160a01b0381358116916020013516610c74565b6102e2600480360360208110156102d257600080fd5b50356001600160a01b0316610caa565b604080516001600160a01b0390971687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b610327610ce9565b604080516001600160a01b039092168252519081900360200190f35b61034b610cf8565b604080519115158252519081900360200190f35b6101fd6004803603602081101561037557600080fd5b50356001600160a01b0316610d01565b6101fd6004803603604081101561039b57600080fd5b506001600160a01b0381358116916020013516610d30565b6101fd600480360360208110156103c957600080fd5b50356001600160a01b0316610d4d565b610327610d68565b6101d4610d7c565b610327600480360360208110156103ff57600080fd5b5035610e38565b6101d46004803603604081101561041c57600080fd5b506001600160a01b038135169060200135610e5f565b610327610fa5565b6101fd610fb4565b6101d46004803603602081101561045857600080fd5b5035610fba565b6101d46004803603604081101561047557600080fd5b506001600160a01b038135169060200135611231565b6101fd600480360360208110156104a157600080fd5b50356001600160a01b031661150b565b6101d4600480360360608110156104c757600080fd5b506001600160a01b0381358116916020810135909116906040013561153d565b6101fd600480360360408110156104fd57600080fd5b506001600160a01b03813581169160200135166115d9565b6101d46115f6565b6101fd6004803603602081101561053357600080fd5b50356001600160a01b0316611619565b61054b6116cc565b600280546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229181900360200190a150565b6105a76116cc565b60045460ff16151581151514156105bd57610616565b6004805460ff1916821515179081905560ff16156105da57426003555b6004546040805160ff90921615158252517f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec59181900360200190a15b50565b60095490565b6001600160a01b0380831660008181526008602090815260408083209486168084529482528083205493835260078252808320948352939052918220546106c991906106bd90670de0b6b3a7640000906106b19061068c9061068089611619565b9063ffffffff61171516565b6001600160a01b0389166000908152600a60205260409020549063ffffffff61177216565b9063ffffffff6117cb16565b9063ffffffff61183516565b90505b92915050565b6001600160a01b0382166000908152600560205260409020600201544211610741576040805162461bcd60e51b815260206004820152601a60248201527f52657761726420706572696f64207374696c6c20616374697665000000000000604482015290519081900360640190fd5b6001600160a01b0382811660009081526005602052604090205416331461076757600080fd5b600081116107bc576040805162461bcd60e51b815260206004820181905260248201527f526577617264206475726174696f6e206d757374206265206e6f6e2d7a65726f604482015290519081900360640190fd5b6001600160a01b0382166000818152600560209081526040918290206001018490558151928352820183905280517fad2f86b01ed93b4b3a150d448c61a4f5d8d38075d3c0c64cc0a26fd6e1f495459281900390910190a15050565b600080546001018082559033905b60065481101561090b5760006006828154811061083f57fe5b6000918252602090912001546001600160a01b0316905061085f81611619565b6001600160a01b0382166000908152600560208190526040909120015561088581610d01565b6001600160a01b03808316600090815260056020526040902060040191909155831615610902576108b6838261061f565b6001600160a01b03808516600081815260086020908152604080832094871680845294825280832095909555600580825285832001549282526007815284822093825292909252919020555b50600101610826565b5060008311610955576040805162461bcd60e51b8152602060048201526011602482015270043616e6e6f74207769746864726177203607c1b604482015290519081900360640190fd5b600954610968908463ffffffff61171516565b600955336000908152600a602052604090205461098b908463ffffffff61171516565b336000818152600a60205260409020919091556004546109c1916101009091046001600160a01b0316908563ffffffff61188f16565b60408051848152905133917f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5919081900360200190a2506000548114610a4e576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b5050565b600080546001018082559033905b600654811015610b4557600060068281548110610a7957fe5b6000918252602090912001546001600160a01b03169050610a9981611619565b6001600160a01b03821660009081526005602081905260409091200155610abf81610d01565b6001600160a01b03808316600090815260056020526040902060040191909155831615610b3c57610af0838261061f565b6001600160a01b03808516600081815260086020908152604080832094871680845294825280832095909555600580825285832001549282526007815284822093825292909252919020555b50600101610a60565b5060005b600654811015610c1c57600060068281548110610b6257fe5b60009182526020808320909101543383526008825260408084206001600160a01b03909216808552919092529120549091508015610c12573360008181526008602090815260408083206001600160a01b0387168085529252822091909155610bd1918363ffffffff61188f16565b6040805182815290516001600160a01b0384169133917f540798df468d7b23d11f156fdb954cb19ad414d150722a7b6d55ba369dea792e9181900360200190a35b5050600101610b49565b50506000548114610616576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b610c7c6116cc565b6001600160a01b03918216600090815260056020526040902080546001600160a01b03191691909216179055565b60056020819052600091825260409091208054600182015460028301546003840154600485015494909501546001600160a01b03909316949193909286565b6002546001600160a01b031681565b60045460ff1681565b6001600160a01b038116600090815260056020526040812060020154610d289042906118e6565b90505b919050565b600760209081526000928352604080842090915290825290205481565b6001600160a01b03166000908152600a602052604090205490565b60045461010090046001600160a01b031681565b6002546001600160a01b03163314610dc55760405162461bcd60e51b8152600401808060200182810382526035815260200180611b1b6035913960400191505060405180910390fd5b600154600254604080516001600160a01b03938416815292909116602083015280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a160028054600180546001600160a01b03199081166001600160a01b03841617909155169055565b60068181548110610e4557fe5b6000918252602090912001546001600160a01b0316905081565b610e676116cc565b6004546001600160a01b03838116610100909204161415610ecf576040805162461bcd60e51b815260206004820152601d60248201527f43616e6e6f74207769746864726177207374616b696e6720746f6b656e000000604482015290519081900360640190fd5b6001600160a01b03821660009081526005602052604090206004015415610f3d576040805162461bcd60e51b815260206004820152601c60248201527f43616e6e6f742077697468647261772072657761726420746f6b656e00000000604482015290519081900360640190fd5b600154610f5d906001600160a01b0384811691168363ffffffff61188f16565b604080516001600160a01b03841681526020810183905281517f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa28929181900390910190a15050565b6001546001600160a01b031681565b60035481565b600080546001019081905560045460ff16156110075760405162461bcd60e51b815260040180806020018281038252603c815260200180611ba0603c913960400191505060405180910390fd5b3360005b6006548110156110f05760006006828154811061102457fe5b6000918252602090912001546001600160a01b0316905061104481611619565b6001600160a01b0382166000908152600560208190526040909120015561106a81610d01565b6001600160a01b038083166000908152600560205260409020600401919091558316156110e75761109b838261061f565b6001600160a01b03808516600081815260086020908152604080832094871680845294825280832095909555600580825285832001549282526007815284822093825292909252919020555b5060010161100b565b5060008311611137576040805162461bcd60e51b815260206004820152600e60248201526d043616e6e6f74207374616b6520360941b604482015290519081900360640190fd5b60095461114a908463ffffffff61183516565b600955336000908152600a602052604090205461116d908463ffffffff61183516565b336000818152600a60205260409020919091556004546111a4916101009091046001600160a01b031690308663ffffffff6118fc16565b60408051848152905133917f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d919081900360200190a2506000548114610a4e576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6000805b60065481101561131a5760006006828154811061124e57fe5b6000918252602090912001546001600160a01b0316905061126e81611619565b6001600160a01b0382166000908152600560208190526040909120015561129481610d01565b6001600160a01b03808316600090815260056020526040902060040191909155831615611311576112c5838261061f565b6001600160a01b03808516600081815260086020908152604080832094871680845294825280832095909555600580825285832001549282526007815284822093825292909252919020555b50600101611235565b506001600160a01b0383811660009081526005602052604090205416331461134157600080fd5b61135c6001600160a01b03841633308563ffffffff6118fc16565b6001600160a01b03831660009081526005602052604090206002015442106113cc576001600160a01b0383166000908152600560205260409020600101546113ab90839063ffffffff6117cb16565b6001600160a01b03841660009081526005602052604090206003015561147b565b6001600160a01b0383166000908152600560205260408120600201546113f8904263ffffffff61171516565b6001600160a01b0385166000908152600560205260408120600301549192509061142990839063ffffffff61177216565b6001600160a01b03861660009081526005602052604090206001015490915061145c906106b1868463ffffffff61183516565b6001600160a01b03861660009081526005602052604090206003015550505b6001600160a01b038316600090815260056020526040902042600482018190556001909101546114b1919063ffffffff61183516565b6001600160a01b03841660009081526005602090815260409182902060020192909255805184815290517fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d929181900390910190a1505050565b6001600160a01b03811660009081526005602052604081206001810154600390910154610d289163ffffffff61177216565b6115456116cc565b6001600160a01b0383166000908152600560205260409020600101541561156b57600080fd5b6006805460018181019092557ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b039586166001600160a01b031991821681179092556000918252600560205260409091208054949095169316929092178355910155565b600860209081526000928352604080842090915290825290205481565b336000908152600a602052604090205461160f90610818565b611617610a52565b565b60006009546000141561164957506001600160a01b03811660009081526005602081905260409091200154610d2b565b6009546001600160a01b03831660009081526005602052604090206003810154600490910154610d28926116a39290916106b191670de0b6b3a764000091611697919082906106808b610d01565b9063ffffffff61177216565b6001600160a01b038416600090815260056020819052604090912001549063ffffffff61183516565b6001546001600160a01b031633146116175760405162461bcd60e51b815260040180806020018281038252602f815260200180611b50602f913960400191505060405180910390fd5b60008282111561176c576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600082611781575060006106cc565b8282028284828161178e57fe5b04146106c95760405162461bcd60e51b8152600401808060200182810382526021815260200180611b7f6021913960400191505060405180910390fd5b6000808211611821576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b600082848161182c57fe5b04949350505050565b6000828201838110156106c9576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526118e190849061195c565b505050565b60008183106118f557816106c9565b5090919050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261195690859061195c565b50505050565b61196e826001600160a01b0316611b14565b6119bf576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106119fd5780518252601f1990920191602091820191016119de565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611a5f576040519150601f19603f3d011682016040523d82523d6000602084013e611a64565b606091505b509150915081611abb576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b80511561195657808060200190516020811015611ad757600080fd5b50516119565760405162461bcd60e51b815260040180806020018281038252602a815260200180611bdc602a913960400191505060405180910390fd5b3b15159056fe596f75206d757374206265206e6f6d696e61746564206265666f726520796f752063616e20616363657074206f776e6572736869704f6e6c792074686520636f6e7472616374206f776e6572206d617920706572666f726d207468697320616374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775468697320616374696f6e2063616e6e6f7420626520706572666f726d6564207768696c652074686520636f6e7472616374206973207061757365645361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a72315820731cf4abf8d8a8130d07577cfe68335a7251c496d352327e8a55c8dad03177df64736f6c63430005110032