Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 434 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw | 21435460 | 4 days ago | IN | 0 ETH | 0.00130879 | ||||
Get Reward | 21435457 | 4 days ago | IN | 0 ETH | 0.00074719 | ||||
Get Reward | 21435456 | 4 days ago | IN | 0 ETH | 0.00073137 | ||||
Withdraw | 20994239 | 65 days ago | IN | 0 ETH | 0.00188276 | ||||
Get Reward | 19275864 | 305 days ago | IN | 0 ETH | 0.00343464 | ||||
Withdraw | 19275847 | 306 days ago | IN | 0 ETH | 0.00382899 | ||||
Stake | 18625018 | 397 days ago | IN | 0 ETH | 0.00268887 | ||||
Get Reward | 18625007 | 397 days ago | IN | 0 ETH | 0.00245934 | ||||
Withdraw | 18625003 | 397 days ago | IN | 0 ETH | 0.00332952 | ||||
Stake | 18577113 | 403 days ago | IN | 0 ETH | 0.00276655 | ||||
Get Reward | 18577106 | 404 days ago | IN | 0 ETH | 0.0023323 | ||||
Withdraw | 18577104 | 404 days ago | IN | 0 ETH | 0.0035531 | ||||
Stake | 18123267 | 467 days ago | IN | 0 ETH | 0.00063794 | ||||
Stake | 18119061 | 468 days ago | IN | 0 ETH | 0.0009458 | ||||
Get Reward | 18096604 | 471 days ago | IN | 0 ETH | 0.00091145 | ||||
Withdraw | 18096598 | 471 days ago | IN | 0 ETH | 0.00111024 | ||||
Get Reward | 17879789 | 501 days ago | IN | 0 ETH | 0.00192331 | ||||
Withdraw | 17879758 | 501 days ago | IN | 0 ETH | 0.0024607 | ||||
Get Reward | 17879743 | 501 days ago | IN | 0 ETH | 0.00300436 | ||||
Get Reward | 17358401 | 574 days ago | IN | 0 ETH | 0.00370392 | ||||
Withdraw | 17279973 | 585 days ago | IN | 0 ETH | 0.00834352 | ||||
Get Reward | 16669310 | 672 days ago | IN | 0 ETH | 0.00321988 | ||||
Get Reward | 16643360 | 675 days ago | IN | 0 ETH | 0.00307828 | ||||
Get Reward | 16597503 | 682 days ago | IN | 0 ETH | 0.00174784 | ||||
Withdraw | 16596963 | 682 days ago | IN | 0 ETH | 0.0016583 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
MultiStakingRewards
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-04-15 */ pragma solidity 0.6.12; /** * @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); } /** * @dev Standard math utilities missing in the Solidity language. */ 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); } } /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the `nonReentrant` modifier * available, which can be aplied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. */ 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"); } } interface IRewardsDistributionRecipient { function notifyRewardAmount(address _rewardToken, uint256 reward) external; } interface IWrappedERC20 { function wrap(address _to, uint _amount) external; function unwrap(address _to, uint _amount) external; } // A multistakingreward contract that allows stakers to staking a single token and recieve various reward tokens. // Forked from the Uniswap staking reward contract at https://etherscan.io/address/0x7FBa4B8Dc5E7616e59622806932DBea72537A56b#code // with the following changes: // - Expand from single reward token to a list of reward tokens // - allow governance to rescue unclaimed tokens contract MultiStakingRewards is IRewardsDistributionRecipient, ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20; /* ========== STRUCTS ========== */ // Info of each reward pool. struct RewardPool { IERC20 rewardToken; // Address of reward token. uint256 periodFinish; // timestamp of when this reward pool finishes distribution uint256 rewardRate; // amount of rewards distributed per unit of time uint256 rewardsDuration; // duration of distribution uint256 lastUpdateTime; // timestamp of when reward info was last updated uint256 rewardPerTokenStored; // current rewards per token based on total rewards and total staked mapping(address => uint256) userRewardPerTokenPaid; // amount of rewards per token already paided out to user mapping(address => uint256) rewards; // amount of rewards user has earned bool isActive; // mark if the pool is active } /* ========== STATE VARIABLES ========== */ address public rewardsDistribution; address public governance; IERC20 public stakingToken; IWrappedERC20 public wStakingToken; // wrapped stakingToken is used to reward stakers with more stakingToken uint256 public totalSupply; mapping(address => uint256) public balances; mapping(address => RewardPool) public rewardPools; // reward token to reward pool mapping address[] public activeRewardPools; // list of reward tokens that are distributing rewards /* ========== CONSTRUCTOR ========== */ constructor(address _stakingToken, address _wStakingToken, address _rewardsDistribution) public { stakingToken = IERC20(_stakingToken); wStakingToken = IWrappedERC20(_wStakingToken); rewardsDistribution = _rewardsDistribution; governance = msg.sender; } /* ========== VIEWS ========== */ function activeRewardPoolsLength() external view returns (uint256) { return activeRewardPools.length; } function lastTimeRewardApplicable(address _rewardToken) public view returns (uint256) { RewardPool storage pool = rewardPools[_rewardToken]; return Math.min(block.timestamp, pool.periodFinish); } function rewardPerToken(address _rewardToken) public view returns (uint256) { RewardPool storage pool = rewardPools[_rewardToken]; if (totalSupply == 0) { return pool.rewardPerTokenStored; } return pool.rewardPerTokenStored.add( lastTimeRewardApplicable(_rewardToken).sub(pool.lastUpdateTime).mul(pool.rewardRate).mul(1e18).div(totalSupply) ); } function earned(address _rewardToken, address _account) public view returns (uint256) { RewardPool storage pool = rewardPools[_rewardToken]; return balances[_account].mul(rewardPerToken(_rewardToken).sub(pool.userRewardPerTokenPaid[_account])).div(1e18).add(pool.rewards[_account]); } function getRewardForDuration(address _rewardToken) external view returns (uint256) { RewardPool storage pool = rewardPools[_rewardToken]; return pool.rewardRate.mul(pool.rewardsDuration); } function periodFinish(address _rewardToken) public view returns (uint256) { RewardPool storage pool = rewardPools[_rewardToken]; return pool.periodFinish; } function rewardRate(address _rewardToken) public view returns (uint256) { RewardPool storage pool = rewardPools[_rewardToken]; return pool.rewardRate; } function rewardsDuration(address _rewardToken) public view returns (uint256) { RewardPool storage pool = rewardPools[_rewardToken]; return pool.rewardsDuration; } function lastUpdateTime(address _rewardToken) public view returns (uint256) { RewardPool storage pool = rewardPools[_rewardToken]; return pool.lastUpdateTime; } function rewardPerTokenStored(address _rewardToken) public view returns (uint256) { RewardPool storage pool = rewardPools[_rewardToken]; return pool.rewardPerTokenStored; } function userRewardPerTokenPaid(address _rewardToken, address _account) public view returns (uint256) { RewardPool storage pool = rewardPools[_rewardToken]; return pool.userRewardPerTokenPaid[_account]; } function rewards(address _rewardToken, address _account) public view returns (uint256) { RewardPool storage pool = rewardPools[_rewardToken]; return pool.rewards[_account]; } /* ========== MUTATIVE FUNCTIONS ========== */ function stake(uint256 amount) external nonReentrant updateActiveRewards(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 updateActiveRewards(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(address _rewardToken) external nonReentrant updateReward(_rewardToken, msg.sender) { _getReward(_rewardToken); } function getAllActiveRewards() public nonReentrant updateActiveRewards(msg.sender) { for (uint i = 0; i < activeRewardPools.length; i++) { _getReward(activeRewardPools[i]); } } function _getReward(address _rewardToken) internal { RewardPool storage pool = rewardPools[_rewardToken]; require(pool.isActive, "pool is inactive"); uint256 reward = pool.rewards[msg.sender]; if (reward > 0) { pool.rewards[msg.sender] = 0; // If reward token is wrapped version of staking token, auto unwrap into underlying to user if (address(pool.rewardToken) == address(wStakingToken)) { wStakingToken.unwrap(msg.sender, reward); } else { pool.rewardToken.safeTransfer(msg.sender, reward); } emit RewardPaid(address(pool.rewardToken), msg.sender, reward); } } function exit() external { withdraw(balances[msg.sender]); getAllActiveRewards(); } /* ========== RESTRICTED FUNCTIONS ========== */ function notifyRewardAmount(address _rewardToken, uint256 _amount) external override onlyRewardsDistribution updateReward(_rewardToken, address(0)) { RewardPool storage pool = rewardPools[_rewardToken]; if (block.timestamp >= pool.periodFinish) { pool.rewardRate = _amount.div(pool.rewardsDuration); } else { uint256 remaining = pool.periodFinish.sub(block.timestamp); uint256 leftover = remaining.mul(pool.rewardRate); pool.rewardRate = _amount.add(leftover).div(pool.rewardsDuration); } // Ensure the provided reward amount is not more than the balance in the contract. // This keeps the reward rate in the right range, preventing overflows due to // very high values of rewardRate in the earned and rewardsPerToken functions; // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow. uint balance = pool.rewardToken.balanceOf(address(this)); require(pool.rewardRate <= balance.div(pool.rewardsDuration), "Provided reward too high"); pool.lastUpdateTime = block.timestamp; pool.periodFinish = block.timestamp.add(pool.rewardsDuration); emit RewardAdded(_rewardToken, _amount); } // Add new reward pool to list // NOTE: DO NOT add same pool twice while active. function addRewardPool( address _rewardToken, uint256 _rewardsDuration ) external onlyGov { rewardPools[_rewardToken] = RewardPool({ rewardToken: IERC20(_rewardToken), periodFinish: 0, rewardRate: 0, rewardsDuration: _rewardsDuration, lastUpdateTime: 0, rewardPerTokenStored: 0, isActive: true }); activeRewardPools.push(_rewardToken); } // Remove pool from active list function inactivateRewardPool(address _rewardToken) external onlyGov { // find the index uint indexToDelete = 0; bool found = false; for (uint i = 0; i < activeRewardPools.length; i++) { if (activeRewardPools[i] == _rewardToken) { indexToDelete = i; found = true; break; } } require(found, "element not found"); _inactivateRewardPool(indexToDelete); } // In case the list gets so large and make iteration impossible function inactivateRewardPoolByIndex(uint256 _index) external onlyGov { _inactivateRewardPool(_index); } function _inactivateRewardPool(uint256 _index) internal { RewardPool storage pool = rewardPools[activeRewardPools[_index]]; pool.isActive = false; // we don't care about the ordering of the active reward pool array // so we can just swap the element to delete with the last element activeRewardPools[_index] = activeRewardPools[activeRewardPools.length - 1]; activeRewardPools.pop(); } // Allow governance to rescue unclaimed inactive rewards function rescue(address _rewardToken) external onlyGov { require(_rewardToken != address(stakingToken), "Cannot withdraw staking token"); RewardPool storage pool = rewardPools[_rewardToken]; require(pool.isActive == false, "Cannot withdraw active reward token"); uint _balance = IERC20(_rewardToken).balanceOf(address(this)); IERC20(_rewardToken).safeTransfer(governance, _balance); } /* ========== RESTRICTED FUNCTIONS ========== */ function setRewardsDistribution(address _rewardsDistribution) external { require(msg.sender == governance, "!governance"); rewardsDistribution = _rewardsDistribution; } function setGov(address _gov) external { require(msg.sender == governance, "!governance"); governance = _gov; } /* ========== MODIFIERS ========== */ modifier updateActiveRewards(address _account) { for (uint i = 0; i < activeRewardPools.length; i++) { RewardPool storage pool = rewardPools[activeRewardPools[i]]; pool.rewardPerTokenStored = rewardPerToken(address(pool.rewardToken)); pool.lastUpdateTime = lastTimeRewardApplicable(address(pool.rewardToken)); if (_account != address(0)) { pool.rewards[_account] = earned(address(pool.rewardToken), _account); pool.userRewardPerTokenPaid[_account] = pool.rewardPerTokenStored; } } _; } modifier updateReward(address _rewardToken, address _account) { RewardPool storage pool = rewardPools[_rewardToken]; pool.rewardPerTokenStored = rewardPerToken(address(pool.rewardToken)); pool.lastUpdateTime = lastTimeRewardApplicable(address(pool.rewardToken)); if (_account != address(0)) { pool.rewards[_account] = earned(address(pool.rewardToken), _account); pool.userRewardPerTokenPaid[_account] = pool.rewardPerTokenStored; } _; } modifier onlyGov() { require(msg.sender == governance, "!governance"); _; } modifier onlyRewardsDistribution() { require(msg.sender == rewardsDistribution, "!rewardsDistribution"); _; } /* ========== EVENTS ========== */ event RewardAdded(address indexed rewardToken, uint256 amount); event Staked(address indexed user, uint256 amount); event Withdrawn(address indexed user, uint256 amount); event RewardPaid(address indexed rewardToken, address indexed user, uint256 reward); }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_stakingToken","type":"address"},{"internalType":"address","name":"_wStakingToken","type":"address"},{"internalType":"address","name":"_rewardsDistribution","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rewardToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rewardToken","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"activeRewardPools","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"activeRewardPoolsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"uint256","name":"_rewardsDuration","type":"uint256"}],"name":"addRewardPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"address","name":"_account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllActiveRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"getRewardForDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"inactivateRewardPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"inactivateRewardPoolByIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"rescue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardPools","outputs":[{"internalType":"contract IERC20","name":"rewardToken","type":"address"},{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"rewardsDuration","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"address","name":"_account","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsDistribution","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"}],"name":"rewardsDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gov","type":"address"}],"name":"setGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsDistribution","type":"address"}],"name":"setRewardsDistribution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"address","name":"_account","type":"address"}],"name":"userRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wStakingToken","outputs":[{"internalType":"contract IWrappedERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5060405161209e38038061209e8339818101604052606081101561003357600080fd5b508051602082015160409092015160016000819055600380546001600160a01b039485166001600160a01b03199182161790915560048054958516958216959095179094558054929091169183169190911790556002805490911633179055611ffd806100a16000396000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c80637035ab981161010f578063bcd11014116100a2578063e70b9e2711610071578063e70b9e27146105d5578063e9fad8ee14610603578063eb9e5ddc1461060b578063f122977714610613576101f0565b8063bcd110141461053d578063c00007b014610563578063cfad57a214610589578063da09d19d146105af576101f0565b80639ce43f90116100de5780639ce43f90146104c6578063a694fc3a146104ec578063b305f18a14610509578063b66503cf14610511576101f0565b80637035ab981461044d57806372f702f31461047b5780637eb4896614610483578063839006f2146104a0576101f0565b80632e1a7d4d116101875780634d5255e4116101565780634d5255e4146103f15780635aa6e675146103f95780635d91035114610401578063638634ee14610427576101f0565b80632e1a7d4d1461033c57806333d4cbf314610359578063372d94481461037f5780633fc6df6e146103e9576101f0565b8063211dc32d116101c3578063211dc32d1461029c578063221ca18c146102ca57806327e235e3146102f05780632ce9aead14610316576101f0565b806318160ddd146101f5578063197621431461020f5780631c5ef433146102375780631dfa8e8114610263575b600080fd5b6101fd610639565b60408051918252519081900360200190f35b6102356004803603602081101561022557600080fd5b50356001600160a01b031661063f565b005b6102356004803603604081101561024d57600080fd5b506001600160a01b0381351690602001356106ae565b6102806004803603602081101561027957600080fd5b50356107d0565b604080516001600160a01b039092168252519081900360200190f35b6101fd600480360360408110156102b257600080fd5b506001600160a01b03813581169160200135166107f7565b6101fd600480360360208110156102e057600080fd5b50356001600160a01b031661088e565b6101fd6004803603602081101561030657600080fd5b50356001600160a01b03166108b0565b6101fd6004803603602081101561032c57600080fd5b50356001600160a01b03166108c2565b6102356004803603602081101561035257600080fd5b50356108e0565b6102356004803603602081101561036f57600080fd5b50356001600160a01b0316610adf565b6103a56004803603602081101561039557600080fd5b50356001600160a01b0316610bd7565b604080516001600160a01b0390981688526020880196909652868601949094526060860192909252608085015260a0840152151560c0830152519081900360e00190f35b610280610c21565b610235610c30565b610280610d99565b6101fd6004803603602081101561041757600080fd5b50356001600160a01b0316610da8565b6101fd6004803603602081101561043d57600080fd5b50356001600160a01b0316610dc6565b6101fd6004803603604081101561046357600080fd5b506001600160a01b0381358116916020013516610df5565b610280610e24565b6102356004803603602081101561049957600080fd5b5035610e33565b610235600480360360208110156104b657600080fd5b50356001600160a01b0316610e89565b6101fd600480360360208110156104dc57600080fd5b50356001600160a01b031661102d565b6102356004803603602081101561050257600080fd5b503561104b565b610280611244565b6102356004803603604081101561052757600080fd5b506001600160a01b038135169060200135611253565b6101fd6004803603602081101561055357600080fd5b50356001600160a01b0316611511565b6102356004803603602081101561057957600080fd5b50356001600160a01b031661153c565b6102356004803603602081101561059f57600080fd5b50356001600160a01b0316611634565b6101fd600480360360208110156105c557600080fd5b50356001600160a01b03166116a3565b6101fd600480360360408110156105eb57600080fd5b506001600160a01b03813581169160200135166116c1565b6102356116ed565b6101fd611710565b6101fd6004803603602081101561062957600080fd5b50356001600160a01b0316611716565b60055481565b6002546001600160a01b0316331461068c576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031633146106fb576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6040805160e0810182526001600160a01b0393841680825260006020808401828152848601838152606086019788526080860184815260a08701858152600160c089018181528888526007909652988620975188549b166001600160a01b03199b8c161788559251878901559051600287015596516003860155955160048501559451600584015593516008928301805491151560ff199092169190911790558154928301825592527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3018054909216179055565b600881815481106107dd57fe5b6000918252602090912001546001600160a01b0316905081565b6001600160a01b03808316600090815260076020818152604080842094861684529184018152818320546006850190915290822054919291610884919061087e90670de0b6b3a76400009061087890610859906108538b611716565b9061177f565b6001600160a01b038916600090815260066020526040902054906117c1565b9061181a565b9061185c565b9150505b92915050565b6001600160a01b0381166000908152600760205260409020600201545b919050565b60066020526000908152604090205481565b6001600160a01b031660009081526007602052604090206004015490565b600080546001018082559033905b6008548110156109c0576000600760006008848154811061090b57fe5b60009182526020808320909101546001600160a01b039081168452908301939093526040909101902080549092506109439116611716565b6005820155805461095c906001600160a01b0316610dc6565b60048201556001600160a01b038316156109b7578054610985906001600160a01b0316846107f7565b6001600160a01b0384166000908152600783016020908152604080832093909355600584015460068501909152919020555b506001016108ee565b5060008311610a0a576040805162461bcd60e51b8152602060048201526011602482015270043616e6e6f74207769746864726177203607c1b604482015290519081900360640190fd5b600554610a17908461177f565b60055533600090815260066020526040902054610a34908461177f565b33600081815260066020526040902091909155600354610a60916001600160a01b0390911690856118b6565b60408051848152905133917f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5919081900360200190a2506000548114610adb576040805162461bcd60e51b815260206004820152601f6024820152600080516020611f3a833981519152604482015290519081900360640190fd5b5050565b6002546001600160a01b03163314610b2c576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b60008060005b600854811015610b8257836001600160a01b031660088281548110610b5357fe5b6000918252602090912001546001600160a01b03161415610b7a5780925060019150610b82565b600101610b32565b5080610bc9576040805162461bcd60e51b8152602060048201526011602482015270195b195b595b9d081b9bdd08199bdd5b99607a1b604482015290519081900360640190fd5b610bd282611908565b505050565b60076020526000908152604090208054600182015460028301546003840154600485015460058601546008909601546001600160a01b039095169593949293919290919060ff1687565b6001546001600160a01b031681565b600080546001018082559033905b600854811015610d105760006007600060088481548110610c5b57fe5b60009182526020808320909101546001600160a01b03908116845290830193909352604090910190208054909250610c939116611716565b60058201558054610cac906001600160a01b0316610dc6565b60048201556001600160a01b03831615610d07578054610cd5906001600160a01b0316846107f7565b6001600160a01b0384166000908152600783016020908152604080832093909355600584015460068501909152919020555b50600101610c3e565b5060005b600854811015610d5057610d4860088281548110610d2e57fe5b6000918252602090912001546001600160a01b03166119e5565b600101610d14565b50506000548114610d96576040805162461bcd60e51b815260206004820152601f6024820152600080516020611f3a833981519152604482015290519081900360640190fd5b50565b6002546001600160a01b031681565b6001600160a01b031660009081526007602052604090206003015490565b6001600160a01b03811660009081526007602052604081206001810154610dee904290611b59565b9392505050565b6001600160a01b0391821660009081526007602090815260408083209390941682526006909201909152205490565b6003546001600160a01b031681565b6002546001600160a01b03163314610e80576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b610d9681611908565b6002546001600160a01b03163314610ed6576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6003546001600160a01b0382811691161415610f39576040805162461bcd60e51b815260206004820152601d60248201527f43616e6e6f74207769746864726177207374616b696e6720746f6b656e000000604482015290519081900360640190fd5b6001600160a01b0381166000908152600760205260409020600881015460ff1615610f955760405162461bcd60e51b8152600401808060200182810382526023815260200180611f7b6023913960400191505060405180910390fd5b6000826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610fe457600080fd5b505afa158015610ff8573d6000803e3d6000fd5b505050506040513d602081101561100e57600080fd5b5051600254909150610bd2906001600160a01b038581169116836118b6565b6001600160a01b031660009081526007602052604090206005015490565b600080546001018082559033905b60085481101561112b576000600760006008848154811061107657fe5b60009182526020808320909101546001600160a01b039081168452908301939093526040909101902080549092506110ae9116611716565b600582015580546110c7906001600160a01b0316610dc6565b60048201556001600160a01b038316156111225780546110f0906001600160a01b0316846107f7565b6001600160a01b0384166000908152600783016020908152604080832093909355600584015460068501909152919020555b50600101611059565b5060008311611172576040805162461bcd60e51b815260206004820152600e60248201526d043616e6e6f74207374616b6520360941b604482015290519081900360640190fd5b60055461117f908461185c565b6005553360009081526006602052604090205461119c908461185c565b336000818152600660205260409020919091556003546111c9916001600160a01b03909116903086611b6f565b60408051848152905133917f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d919081900360200190a2506000548114610adb576040805162461bcd60e51b815260206004820152601f6024820152600080516020611f3a833981519152604482015290519081900360640190fd5b6004546001600160a01b031681565b6001546001600160a01b031633146112a9576040805162461bcd60e51b815260206004820152601460248201527310b932bbb0b93239a234b9ba3934b13aba34b7b760611b604482015290519081900360640190fd5b6001600160a01b038083166000908152600760205260408120805485936112d09116611716565b600582015580546112e9906001600160a01b0316610dc6565b60048201556001600160a01b03821615611344578054611312906001600160a01b0316836107f7565b6001600160a01b0383166000908152600783016020908152604080832093909355600584015460068501909152919020555b6001600160a01b03851660009081526007602052604090206001810154421061138157600381015461137790869061181a565b60028201556113cc565b6001810154600090611393904261177f565b905060006113ae8360020154836117c190919063ffffffff16565b60038401549091506113c490610878898461185c565b600284015550505b8054604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561141657600080fd5b505afa15801561142a573d6000803e3d6000fd5b505050506040513d602081101561144057600080fd5b5051600383015490915061145590829061181a565b826002015411156114ad576040805162461bcd60e51b815260206004820152601860248201527f50726f76696465642072657761726420746f6f20686967680000000000000000604482015290519081900360640190fd5b426004830181905560038301546114c4919061185c565b60018301556040805187815290516001600160a01b038916917fac24935fd910bc682b5ccb1a07b718cadf8cf2f6d1404c4f3ddc3662dae40e29919081900360200190a250505050505050565b6001600160a01b038116600090815260076020526040812060038101546002820154610dee916117c1565b600080546001018082556001600160a01b038084168352600760205260409092208054919284923392916115709116611716565b60058201558054611589906001600160a01b0316610dc6565b60048201556001600160a01b038216156115e45780546115b2906001600160a01b0316836107f7565b6001600160a01b0383166000908152600783016020908152604080832093909355600584015460068501909152919020555b6115ed856119e5565b5050506000548114610adb576040805162461bcd60e51b815260206004820152601f6024820152600080516020611f3a833981519152604482015290519081900360640190fd5b6002546001600160a01b03163314611681576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b031660009081526007602052604090206001015490565b6001600160a01b0391821660009081526007602081815260408084209490951683529201909152205490565b33600090815260066020526040902054611706906108e0565b61170e610c30565b565b60085490565b6001600160a01b0381166000908152600760205260408120600554611740576005015490506108ab565b610dee611774600554610878670de0b6b3a764000061176e866002015461176e88600401546108538c610dc6565b906117c1565b60058301549061185c565b6000610dee83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611bcf565b6000826117d057506000610888565b828202828482816117dd57fe5b0414610dee5760405162461bcd60e51b8152600401808060200182810382526021815260200180611f5a6021913960400191505060405180910390fd5b6000610dee83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611c66565b600082820183811015610dee576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610bd2908490611ccb565b6000600760006008848154811061191b57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190206008808201805460ff19169055805491925090600019810190811061196057fe5b600091825260209091200154600880546001600160a01b03909216918490811061198657fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060088054806119bf57fe5b600082815260209020810160001990810180546001600160a01b03191690550190555050565b6001600160a01b0381166000908152600760205260409020600881015460ff16611a49576040805162461bcd60e51b815260206004820152601060248201526f706f6f6c20697320696e61637469766560801b604482015290519081900360640190fd5b3360009081526007820160205260409020548015610bd25733600090815260078301602052604081205560045482546001600160a01b0390811691161415611afc5760048054604080516339f4769360e01b8152339381019390935260248301849052516001600160a01b03909116916339f4769391604480830192600092919082900301818387803b158015611adf57600080fd5b505af1158015611af3573d6000803e3d6000fd5b50505050611b12565b8154611b12906001600160a01b031633836118b6565b815460408051838152905133926001600160a01b0316917f540798df468d7b23d11f156fdb954cb19ad414d150722a7b6d55ba369dea792e919081900360200190a3505050565b6000818310611b685781610dee565b5090919050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611bc9908590611ccb565b50505050565b60008184841115611c5e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c23578181015183820152602001611c0b565b50505050905090810190601f168015611c505780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183611cb55760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611c23578181015183820152602001611c0b565b506000838581611cc157fe5b0495945050505050565b6060611d20826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611d7c9092919063ffffffff16565b805190915015610bd257808060200190516020811015611d3f57600080fd5b5051610bd25760405162461bcd60e51b815260040180806020018281038252602a815260200180611f9e602a913960400191505060405180910390fd5b6060611d8b8484600085611d93565b949350505050565b6060611d9e85611f00565b611def576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310611e2e5780518252601f199092019160209182019101611e0f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611e90576040519150601f19603f3d011682016040523d82523d6000602084013e611e95565b606091505b50915091508115611ea9579150611d8b9050565b805115611eb95780518082602001fd5b60405162461bcd60e51b8152602060048201818152865160248401528651879391928392604401919085019080838360008315611c23578181015183820152602001611c0b565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590611d8b57505015159291505056fe5265656e7472616e637947756172643a207265656e7472616e742063616c6c00536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7743616e6e6f74207769746864726177206163746976652072657761726420746f6b656e5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212205b11464490a30ddd92b331033567dc8ec70082e302609e2fd25086fe43a630ce64736f6c634300060c0033000000000000000000000000b5495a8d85ee18cfd0d2816993658d88af08bef4000000000000000000000000433aacf5c3d1f1f9869aebc05878db83bc8f2cce000000000000000000000000addcdf97c6db085440b6ddc85ff88d12b8b28ac5
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101f05760003560e01c80637035ab981161010f578063bcd11014116100a2578063e70b9e2711610071578063e70b9e27146105d5578063e9fad8ee14610603578063eb9e5ddc1461060b578063f122977714610613576101f0565b8063bcd110141461053d578063c00007b014610563578063cfad57a214610589578063da09d19d146105af576101f0565b80639ce43f90116100de5780639ce43f90146104c6578063a694fc3a146104ec578063b305f18a14610509578063b66503cf14610511576101f0565b80637035ab981461044d57806372f702f31461047b5780637eb4896614610483578063839006f2146104a0576101f0565b80632e1a7d4d116101875780634d5255e4116101565780634d5255e4146103f15780635aa6e675146103f95780635d91035114610401578063638634ee14610427576101f0565b80632e1a7d4d1461033c57806333d4cbf314610359578063372d94481461037f5780633fc6df6e146103e9576101f0565b8063211dc32d116101c3578063211dc32d1461029c578063221ca18c146102ca57806327e235e3146102f05780632ce9aead14610316576101f0565b806318160ddd146101f5578063197621431461020f5780631c5ef433146102375780631dfa8e8114610263575b600080fd5b6101fd610639565b60408051918252519081900360200190f35b6102356004803603602081101561022557600080fd5b50356001600160a01b031661063f565b005b6102356004803603604081101561024d57600080fd5b506001600160a01b0381351690602001356106ae565b6102806004803603602081101561027957600080fd5b50356107d0565b604080516001600160a01b039092168252519081900360200190f35b6101fd600480360360408110156102b257600080fd5b506001600160a01b03813581169160200135166107f7565b6101fd600480360360208110156102e057600080fd5b50356001600160a01b031661088e565b6101fd6004803603602081101561030657600080fd5b50356001600160a01b03166108b0565b6101fd6004803603602081101561032c57600080fd5b50356001600160a01b03166108c2565b6102356004803603602081101561035257600080fd5b50356108e0565b6102356004803603602081101561036f57600080fd5b50356001600160a01b0316610adf565b6103a56004803603602081101561039557600080fd5b50356001600160a01b0316610bd7565b604080516001600160a01b0390981688526020880196909652868601949094526060860192909252608085015260a0840152151560c0830152519081900360e00190f35b610280610c21565b610235610c30565b610280610d99565b6101fd6004803603602081101561041757600080fd5b50356001600160a01b0316610da8565b6101fd6004803603602081101561043d57600080fd5b50356001600160a01b0316610dc6565b6101fd6004803603604081101561046357600080fd5b506001600160a01b0381358116916020013516610df5565b610280610e24565b6102356004803603602081101561049957600080fd5b5035610e33565b610235600480360360208110156104b657600080fd5b50356001600160a01b0316610e89565b6101fd600480360360208110156104dc57600080fd5b50356001600160a01b031661102d565b6102356004803603602081101561050257600080fd5b503561104b565b610280611244565b6102356004803603604081101561052757600080fd5b506001600160a01b038135169060200135611253565b6101fd6004803603602081101561055357600080fd5b50356001600160a01b0316611511565b6102356004803603602081101561057957600080fd5b50356001600160a01b031661153c565b6102356004803603602081101561059f57600080fd5b50356001600160a01b0316611634565b6101fd600480360360208110156105c557600080fd5b50356001600160a01b03166116a3565b6101fd600480360360408110156105eb57600080fd5b506001600160a01b03813581169160200135166116c1565b6102356116ed565b6101fd611710565b6101fd6004803603602081101561062957600080fd5b50356001600160a01b0316611716565b60055481565b6002546001600160a01b0316331461068c576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031633146106fb576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6040805160e0810182526001600160a01b0393841680825260006020808401828152848601838152606086019788526080860184815260a08701858152600160c089018181528888526007909652988620975188549b166001600160a01b03199b8c161788559251878901559051600287015596516003860155955160048501559451600584015593516008928301805491151560ff199092169190911790558154928301825592527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3018054909216179055565b600881815481106107dd57fe5b6000918252602090912001546001600160a01b0316905081565b6001600160a01b03808316600090815260076020818152604080842094861684529184018152818320546006850190915290822054919291610884919061087e90670de0b6b3a76400009061087890610859906108538b611716565b9061177f565b6001600160a01b038916600090815260066020526040902054906117c1565b9061181a565b9061185c565b9150505b92915050565b6001600160a01b0381166000908152600760205260409020600201545b919050565b60066020526000908152604090205481565b6001600160a01b031660009081526007602052604090206004015490565b600080546001018082559033905b6008548110156109c0576000600760006008848154811061090b57fe5b60009182526020808320909101546001600160a01b039081168452908301939093526040909101902080549092506109439116611716565b6005820155805461095c906001600160a01b0316610dc6565b60048201556001600160a01b038316156109b7578054610985906001600160a01b0316846107f7565b6001600160a01b0384166000908152600783016020908152604080832093909355600584015460068501909152919020555b506001016108ee565b5060008311610a0a576040805162461bcd60e51b8152602060048201526011602482015270043616e6e6f74207769746864726177203607c1b604482015290519081900360640190fd5b600554610a17908461177f565b60055533600090815260066020526040902054610a34908461177f565b33600081815260066020526040902091909155600354610a60916001600160a01b0390911690856118b6565b60408051848152905133917f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5919081900360200190a2506000548114610adb576040805162461bcd60e51b815260206004820152601f6024820152600080516020611f3a833981519152604482015290519081900360640190fd5b5050565b6002546001600160a01b03163314610b2c576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b60008060005b600854811015610b8257836001600160a01b031660088281548110610b5357fe5b6000918252602090912001546001600160a01b03161415610b7a5780925060019150610b82565b600101610b32565b5080610bc9576040805162461bcd60e51b8152602060048201526011602482015270195b195b595b9d081b9bdd08199bdd5b99607a1b604482015290519081900360640190fd5b610bd282611908565b505050565b60076020526000908152604090208054600182015460028301546003840154600485015460058601546008909601546001600160a01b039095169593949293919290919060ff1687565b6001546001600160a01b031681565b600080546001018082559033905b600854811015610d105760006007600060088481548110610c5b57fe5b60009182526020808320909101546001600160a01b03908116845290830193909352604090910190208054909250610c939116611716565b60058201558054610cac906001600160a01b0316610dc6565b60048201556001600160a01b03831615610d07578054610cd5906001600160a01b0316846107f7565b6001600160a01b0384166000908152600783016020908152604080832093909355600584015460068501909152919020555b50600101610c3e565b5060005b600854811015610d5057610d4860088281548110610d2e57fe5b6000918252602090912001546001600160a01b03166119e5565b600101610d14565b50506000548114610d96576040805162461bcd60e51b815260206004820152601f6024820152600080516020611f3a833981519152604482015290519081900360640190fd5b50565b6002546001600160a01b031681565b6001600160a01b031660009081526007602052604090206003015490565b6001600160a01b03811660009081526007602052604081206001810154610dee904290611b59565b9392505050565b6001600160a01b0391821660009081526007602090815260408083209390941682526006909201909152205490565b6003546001600160a01b031681565b6002546001600160a01b03163314610e80576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b610d9681611908565b6002546001600160a01b03163314610ed6576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b6003546001600160a01b0382811691161415610f39576040805162461bcd60e51b815260206004820152601d60248201527f43616e6e6f74207769746864726177207374616b696e6720746f6b656e000000604482015290519081900360640190fd5b6001600160a01b0381166000908152600760205260409020600881015460ff1615610f955760405162461bcd60e51b8152600401808060200182810382526023815260200180611f7b6023913960400191505060405180910390fd5b6000826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610fe457600080fd5b505afa158015610ff8573d6000803e3d6000fd5b505050506040513d602081101561100e57600080fd5b5051600254909150610bd2906001600160a01b038581169116836118b6565b6001600160a01b031660009081526007602052604090206005015490565b600080546001018082559033905b60085481101561112b576000600760006008848154811061107657fe5b60009182526020808320909101546001600160a01b039081168452908301939093526040909101902080549092506110ae9116611716565b600582015580546110c7906001600160a01b0316610dc6565b60048201556001600160a01b038316156111225780546110f0906001600160a01b0316846107f7565b6001600160a01b0384166000908152600783016020908152604080832093909355600584015460068501909152919020555b50600101611059565b5060008311611172576040805162461bcd60e51b815260206004820152600e60248201526d043616e6e6f74207374616b6520360941b604482015290519081900360640190fd5b60055461117f908461185c565b6005553360009081526006602052604090205461119c908461185c565b336000818152600660205260409020919091556003546111c9916001600160a01b03909116903086611b6f565b60408051848152905133917f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d919081900360200190a2506000548114610adb576040805162461bcd60e51b815260206004820152601f6024820152600080516020611f3a833981519152604482015290519081900360640190fd5b6004546001600160a01b031681565b6001546001600160a01b031633146112a9576040805162461bcd60e51b815260206004820152601460248201527310b932bbb0b93239a234b9ba3934b13aba34b7b760611b604482015290519081900360640190fd5b6001600160a01b038083166000908152600760205260408120805485936112d09116611716565b600582015580546112e9906001600160a01b0316610dc6565b60048201556001600160a01b03821615611344578054611312906001600160a01b0316836107f7565b6001600160a01b0383166000908152600783016020908152604080832093909355600584015460068501909152919020555b6001600160a01b03851660009081526007602052604090206001810154421061138157600381015461137790869061181a565b60028201556113cc565b6001810154600090611393904261177f565b905060006113ae8360020154836117c190919063ffffffff16565b60038401549091506113c490610878898461185c565b600284015550505b8054604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561141657600080fd5b505afa15801561142a573d6000803e3d6000fd5b505050506040513d602081101561144057600080fd5b5051600383015490915061145590829061181a565b826002015411156114ad576040805162461bcd60e51b815260206004820152601860248201527f50726f76696465642072657761726420746f6f20686967680000000000000000604482015290519081900360640190fd5b426004830181905560038301546114c4919061185c565b60018301556040805187815290516001600160a01b038916917fac24935fd910bc682b5ccb1a07b718cadf8cf2f6d1404c4f3ddc3662dae40e29919081900360200190a250505050505050565b6001600160a01b038116600090815260076020526040812060038101546002820154610dee916117c1565b600080546001018082556001600160a01b038084168352600760205260409092208054919284923392916115709116611716565b60058201558054611589906001600160a01b0316610dc6565b60048201556001600160a01b038216156115e45780546115b2906001600160a01b0316836107f7565b6001600160a01b0383166000908152600783016020908152604080832093909355600584015460068501909152919020555b6115ed856119e5565b5050506000548114610adb576040805162461bcd60e51b815260206004820152601f6024820152600080516020611f3a833981519152604482015290519081900360640190fd5b6002546001600160a01b03163314611681576040805162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b031660009081526007602052604090206001015490565b6001600160a01b0391821660009081526007602081815260408084209490951683529201909152205490565b33600090815260066020526040902054611706906108e0565b61170e610c30565b565b60085490565b6001600160a01b0381166000908152600760205260408120600554611740576005015490506108ab565b610dee611774600554610878670de0b6b3a764000061176e866002015461176e88600401546108538c610dc6565b906117c1565b60058301549061185c565b6000610dee83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611bcf565b6000826117d057506000610888565b828202828482816117dd57fe5b0414610dee5760405162461bcd60e51b8152600401808060200182810382526021815260200180611f5a6021913960400191505060405180910390fd5b6000610dee83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611c66565b600082820183811015610dee576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610bd2908490611ccb565b6000600760006008848154811061191b57fe5b60009182526020808320909101546001600160a01b0316835282019290925260400190206008808201805460ff19169055805491925090600019810190811061196057fe5b600091825260209091200154600880546001600160a01b03909216918490811061198657fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060088054806119bf57fe5b600082815260209020810160001990810180546001600160a01b03191690550190555050565b6001600160a01b0381166000908152600760205260409020600881015460ff16611a49576040805162461bcd60e51b815260206004820152601060248201526f706f6f6c20697320696e61637469766560801b604482015290519081900360640190fd5b3360009081526007820160205260409020548015610bd25733600090815260078301602052604081205560045482546001600160a01b0390811691161415611afc5760048054604080516339f4769360e01b8152339381019390935260248301849052516001600160a01b03909116916339f4769391604480830192600092919082900301818387803b158015611adf57600080fd5b505af1158015611af3573d6000803e3d6000fd5b50505050611b12565b8154611b12906001600160a01b031633836118b6565b815460408051838152905133926001600160a01b0316917f540798df468d7b23d11f156fdb954cb19ad414d150722a7b6d55ba369dea792e919081900360200190a3505050565b6000818310611b685781610dee565b5090919050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611bc9908590611ccb565b50505050565b60008184841115611c5e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611c23578181015183820152602001611c0b565b50505050905090810190601f168015611c505780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183611cb55760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611c23578181015183820152602001611c0b565b506000838581611cc157fe5b0495945050505050565b6060611d20826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611d7c9092919063ffffffff16565b805190915015610bd257808060200190516020811015611d3f57600080fd5b5051610bd25760405162461bcd60e51b815260040180806020018281038252602a815260200180611f9e602a913960400191505060405180910390fd5b6060611d8b8484600085611d93565b949350505050565b6060611d9e85611f00565b611def576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310611e2e5780518252601f199092019160209182019101611e0f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611e90576040519150601f19603f3d011682016040523d82523d6000602084013e611e95565b606091505b50915091508115611ea9579150611d8b9050565b805115611eb95780518082602001fd5b60405162461bcd60e51b8152602060048201818152865160248401528651879391928392604401919085019080838360008315611c23578181015183820152602001611c0b565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590611d8b57505015159291505056fe5265656e7472616e637947756172643a207265656e7472616e742063616c6c00536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7743616e6e6f74207769746864726177206163746976652072657761726420746f6b656e5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212205b11464490a30ddd92b331033567dc8ec70082e302609e2fd25086fe43a630ce64736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b5495a8d85ee18cfd0d2816993658d88af08bef4000000000000000000000000433aacf5c3d1f1f9869aebc05878db83bc8f2cce000000000000000000000000addcdf97c6db085440b6ddc85ff88d12b8b28ac5
-----Decoded View---------------
Arg [0] : _stakingToken (address): 0xB5495A8D85EE18cfD0d2816993658D88aF08bEF4
Arg [1] : _wStakingToken (address): 0x433aacf5C3d1F1F9869AebC05878Db83BC8f2CCe
Arg [2] : _rewardsDistribution (address): 0xADDcdf97c6Db085440B6dDC85FF88d12b8b28ac5
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000b5495a8d85ee18cfd0d2816993658d88af08bef4
Arg [1] : 000000000000000000000000433aacf5c3d1f1f9869aebc05878db83bc8f2cce
Arg [2] : 000000000000000000000000addcdf97c6db085440b6ddc85ff88d12b8b28ac5
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.063708 | 5,020,275.2414 | $319,831.7 |
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.