ETH Price: $3,015.37 (+4.41%)
Gas: 4 Gwei

Contract

0x0061c52768378b84306b2665f098c3e0b2C03308
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Exit185195802023-11-07 10:48:47190 days ago1699354127IN
0x0061c527...0b2C03308
0 ETH0.0020927525.30381117
Stake184039082023-10-22 5:58:59206 days ago1697954339IN
0x0061c527...0b2C03308
0 ETH0.000542376.26686804
Stake184038952023-10-22 5:56:23206 days ago1697954183IN
0x0061c527...0b2C03308
0 ETH0.00088627.17565731
Get Reward183605672023-10-16 4:32:23212 days ago1697430743IN
0x0061c527...0b2C03308
0 ETH0.000423645.49993987
Stake149712052022-06-16 3:39:04699 days ago1655350744IN
0x0061c527...0b2C03308
0 ETH0.0025578629.2758913
Emergency Withdr...130938492021-08-25 9:50:49994 days ago1629885049IN
0x0061c527...0b2C03308
0 ETH0.0030942659.62549217
Withdraw130938032021-08-25 9:40:06994 days ago1629884406IN
0x0061c527...0b2C03308
0 ETH0.0051288864.78477728
Withdraw130937762021-08-25 9:33:59994 days ago1629884039IN
0x0061c527...0b2C03308
0 ETH0.0055204469.73078883
Withdraw130937282021-08-25 9:23:50994 days ago1629883430IN
0x0061c527...0b2C03308
0 ETH0.0087520573.60358322
Get Reward128728092021-07-21 23:38:531028 days ago1626910733IN
0x0061c527...0b2C03308
0 ETH0.0006407310
Get Reward128051822021-07-11 9:26:501039 days ago1625995610IN
0x0061c527...0b2C03308
0 ETH0.0006687310
Get Reward127655792021-07-05 5:24:431045 days ago1625462683IN
0x0061c527...0b2C03308
0 ETH0.000320365
Withdraw127655732021-07-05 5:23:361045 days ago1625462616IN
0x0061c527...0b2C03308
0 ETH0.0010189210
Exit127282852021-06-29 9:51:511051 days ago1624960311IN
0x0061c527...0b2C03308
0 ETH0.0010142410
Withdraw126922042021-06-23 19:12:391057 days ago1624475559IN
0x0061c527...0b2C03308
0 ETH0.0008709811
Withdraw126871632021-06-23 0:08:291057 days ago1624406909IN
0x0061c527...0b2C03308
0 ETH0.001189810.00000145
Get Reward126694702021-06-20 5:50:151060 days ago1624168215IN
0x0061c527...0b2C03308
0 ETH0.0006407310
Withdraw126694652021-06-20 5:49:321060 days ago1624168172IN
0x0061c527...0b2C03308
0 ETH0.0007919210
Withdraw126685322021-06-20 2:19:371060 days ago1624155577IN
0x0061c527...0b2C03308
0 ETH0.000877488.44
Get Reward126682622021-06-20 1:18:501060 days ago1624151930IN
0x0061c527...0b2C03308
0 ETH0.0010705416.72000023
Withdraw126682602021-06-20 1:18:161060 days ago1624151896IN
0x0061c527...0b2C03308
0 ETH0.01844717212.30000023
Stake126675052021-06-19 22:34:161061 days ago1624142056IN
0x0061c527...0b2C03308
0 ETH0.0010850210
Withdraw126649892021-06-19 13:10:441061 days ago1624108244IN
0x0061c527...0b2C03308
0 ETH0.0010564813.00000145
Get Reward126649802021-06-19 13:08:461061 days ago1624108126IN
0x0061c527...0b2C03308
0 ETH0.0007907310.00000145
Exit126578632021-06-18 10:19:381062 days ago1624011578IN
0x0061c527...0b2C03308
0 ETH0.0011852410
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To Value
183605672023-10-16 4:32:23212 days ago1697430743
0x0061c527...0b2C03308
0.00574434 ETH
183605672023-10-16 4:32:23212 days ago1697430743
0x0061c527...0b2C03308
0.00574434 ETH
128728092021-07-21 23:38:531028 days ago1626910733
0x0061c527...0b2C03308
0.00469134 ETH
128728092021-07-21 23:38:531028 days ago1626910733
0x0061c527...0b2C03308
0.00469134 ETH
128051822021-07-11 9:26:501039 days ago1625995610
0x0061c527...0b2C03308
0.02603816 ETH
128051822021-07-11 9:26:501039 days ago1625995610
0x0061c527...0b2C03308
0.02603816 ETH
127655792021-07-05 5:24:431045 days ago1625462683
0x0061c527...0b2C03308
0.35878946 ETH
127655792021-07-05 5:24:431045 days ago1625462683
0x0061c527...0b2C03308
0.35878946 ETH
127282852021-06-29 9:51:511051 days ago1624960311
0x0061c527...0b2C03308
0.01359646 ETH
127282852021-06-29 9:51:511051 days ago1624960311
0x0061c527...0b2C03308
0.01359646 ETH
126694702021-06-20 5:50:151060 days ago1624168215
0x0061c527...0b2C03308
0.04027781 ETH
126694702021-06-20 5:50:151060 days ago1624168215
0x0061c527...0b2C03308
0.04027781 ETH
126682622021-06-20 1:18:501060 days ago1624151930
0x0061c527...0b2C03308
0.10678947 ETH
126682622021-06-20 1:18:501060 days ago1624151930
0x0061c527...0b2C03308
0.10678947 ETH
126649802021-06-19 13:08:461061 days ago1624108126
0x0061c527...0b2C03308
0.07094326 ETH
126649802021-06-19 13:08:461061 days ago1624108126
0x0061c527...0b2C03308
0.07094326 ETH
126578632021-06-18 10:19:381062 days ago1624011578
0x0061c527...0b2C03308
0.07976423 ETH
126578632021-06-18 10:19:381062 days ago1624011578
0x0061c527...0b2C03308
0.07976423 ETH
126571402021-06-18 7:29:541062 days ago1624001394
0x0061c527...0b2C03308
0.36799231 ETH
126571402021-06-18 7:29:541062 days ago1624001394
0x0061c527...0b2C03308
0.36799231 ETH
126549722021-06-17 23:41:231062 days ago1623973283
0x0061c527...0b2C03308
0.25202355 ETH
126549722021-06-17 23:41:231062 days ago1623973283
0x0061c527...0b2C03308
0.25202355 ETH
126373672021-06-15 6:09:351065 days ago1623737375
0x0061c527...0b2C03308
0.06339441 ETH
126373672021-06-15 6:09:351065 days ago1623737375
0x0061c527...0b2C03308
0.06339441 ETH
126269502021-06-13 15:31:371067 days ago1623598297
0x0061c527...0b2C03308
0.01571211 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CoFiStakingRewards

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 6666 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-10-12
*/

// SPDX-License-Identifier: GPL-3.0-or-later

/**

Author: CoFiX Core, https://cofix.io
Commit hash: v0.9.5-1-g7141c43
Repository: https://github.com/Computable-Finance/CoFiX
Issues: https://github.com/Computable-Finance/CoFiX/issues

*/

pragma solidity 0.6.12;


// 
/**
 * @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;
    }
}

// 
// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
    function safeApprove(address token, address to, uint value) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED');
    }

    function safeTransfer(address token, address to, uint value) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED');
    }

    function safeTransferFrom(address token, address from, address to, uint value) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED');
    }

    function safeTransferETH(address to, uint value) internal {
        (bool success,) = to.call{value:value}(new bytes(0));
        require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
    }
}

// 
/**
 * @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 Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor () internal {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

        _;

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

// 
interface ICoFiStakingRewards {
    // Views

    /// @dev Reward amount represents by per staking token
    function rewardPerToken() external view returns (uint256);

    /// @dev How many reward tokens a user has earned but not claimed at present
    /// @param  account The target account
    /// @return The amount of reward tokens a user earned
    function earned(address account) external view returns (uint256);

    /// @dev How many reward tokens accrued recently
    /// @return The amount of reward tokens accrued recently
    function accrued() external view returns (uint256);

    /// @dev How many stakingToken (XToken) deposited into to this reward pool (staking pool)
    /// @return The total amount of XTokens deposited in this staking pool
    function totalSupply() external view returns (uint256);

    /// @dev How many stakingToken (XToken) deposited by the target account
    /// @param  account The target account
    /// @return The total amount of XToken deposited in this staking pool
    function balanceOf(address account) external view returns (uint256);

    /// @dev Get the address of token for staking in this staking pool
    /// @return The staking token address
    function stakingToken() external view returns (address);

    /// @dev Get the address of token for rewards in this staking pool
    /// @return The rewards token address
    function rewardsToken() external view returns (address);

    // Mutative

    /// @dev Stake/Deposit into the reward pool (staking pool)
    /// @param  amount The target amount
    function stake(uint256 amount) external;

    /// @dev Stake/Deposit into the reward pool (staking pool) for other account
    /// @param  other The target account
    /// @param  amount The target amount
    function stakeForOther(address other, uint256 amount) external;

    /// @dev Withdraw from the reward pool (staking pool), get the original tokens back
    /// @param  amount The target amount
    function withdraw(uint256 amount) external;
    
    /// @dev Withdraw without caring about rewards. EMERGENCY ONLY.
    function emergencyWithdraw() external;

    /// @dev Claim the reward the user earned
    function getReward() external;

    /// @dev Add ETH reward to the staking pool
    function addETHReward() external payable;

    /// @dev User exit the reward pool, it's actually withdraw and getReward
    function exit() external;

    // Events
    event Staked(address indexed user, uint256 amount);
    event StakedForOther(address indexed user, address indexed other, uint256 amount);
    event Withdrawn(address indexed user, uint256 amount);
    event SavingWithdrawn(address indexed to, uint256 amount);
    event EmergencyWithdraw(address indexed user, uint256 amount);
    event RewardPaid(address indexed user, uint256 reward);
    
}

// 
/**
 * @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);
}

// 
interface IWETH {
    function deposit() external payable;
    function transfer(address to, uint value) external returns (bool);
    function withdraw(uint) external;
    function balanceOf(address account) external view returns (uint);
}

// 
// Stake CoFi to earn ETH
contract CoFiStakingRewards is ICoFiStakingRewards, ReentrancyGuard {
    using SafeMath for uint256;

    /* ========== STATE VARIABLES ========== */

    address public override immutable rewardsToken; // WETH, received from CoFiXPair, to reduce gas cost for each swap
    address public override immutable stakingToken; // CoFi

    address public governance;
    uint256 public dividendShare = 20; // 20% to CoFi holders as dividend, 80% to saving for buying back

    uint256 public pendingSavingAmount;

    uint256 public lastUpdateRewardsTokenBalance; // must refresh after each WETH balance change
    uint256 public rewardPerTokenStored;

    mapping(address => uint256) public userRewardPerTokenPaid;
    mapping(address => uint256) public rewards;

    uint256 private _totalSupply;
    mapping(address => uint256) private _balances;

    /* ========== CONSTRUCTOR ========== */

    constructor(
        address _rewardsToken,
        address _stakingToken
    ) public {
        rewardsToken = _rewardsToken;
        stakingToken = _stakingToken;
        governance = msg.sender;
    }

    receive() external payable {}

    /* ========== VIEWS ========== */

    function totalSupply() external override view returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address account) external override view returns (uint256) {
        return _balances[account];
    }

    function rewardPerToken() public override view returns (uint256) {
        if (_totalSupply == 0) {
            // use the old rewardPerTokenStored
            // if not, the new accrued amount will never be distributed to anyone
            return rewardPerTokenStored;
        }
        return
            rewardPerTokenStored.add(
                accrued().mul(1e18).mul(dividendShare).div(_totalSupply).div(100)
            );
    }

    function _rewardPerTokenAndAccrued() internal view returns (uint256, uint256) {
        if (_totalSupply == 0) {
            // use the old rewardPerTokenStored, and accrued should be zero here
            // if not the new accrued amount will never be distributed to anyone
            return (rewardPerTokenStored, 0);
        }
        uint256 _accrued = accrued();
        uint256 _rewardPerToken = rewardPerTokenStored.add(
                _accrued.mul(1e18).mul(dividendShare).div(_totalSupply).div(100) // 50% of accrued to CoFi holders as dividend
            );
        return (_rewardPerToken, _accrued);
    }

    function accrued() public override view returns (uint256) {
        // balance increment of WETH between the last update and now
        uint256 newest = IWETH(rewardsToken).balanceOf(address(this));
        return newest.sub(lastUpdateRewardsTokenBalance); // lastest must be larger than lastUpdate
    }

    function earned(address account) public override view returns (uint256) {
        return _balances[account].mul(rewardPerToken().sub(userRewardPerTokenPaid[account])).div(1e18).add(rewards[account]);
    }

    /* ========== MUTATIVE FUNCTIONS ========== */

    function stake(uint256 amount) external override nonReentrant updateReward(msg.sender) {
        require(amount > 0, "Cannot stake 0");
        _totalSupply = _totalSupply.add(amount);
        _balances[msg.sender] = _balances[msg.sender].add(amount);
        TransferHelper.safeTransferFrom(stakingToken, msg.sender, address(this), amount);
        emit Staked(msg.sender, amount);
    }

    function stakeForOther(address other, uint256 amount) external override nonReentrant updateReward(other) {
        require(amount > 0, "Cannot stake 0");
        _totalSupply = _totalSupply.add(amount);
        _balances[other] = _balances[other].add(amount);
        // be careful: caller should approve to zero after usage
        TransferHelper.safeTransferFrom(stakingToken, msg.sender, address(this), amount);
        emit StakedForOther(msg.sender, other, amount);
    }

    function withdraw(uint256 amount) public override nonReentrant updateReward(msg.sender) {
        require(amount > 0, "Cannot withdraw 0");
        _totalSupply = _totalSupply.sub(amount);
        _balances[msg.sender] = _balances[msg.sender].sub(amount);
        TransferHelper.safeTransfer(stakingToken, msg.sender, amount);
        emit Withdrawn(msg.sender, amount);
    }

    // Withdraw without caring about rewards. EMERGENCY ONLY.
    function emergencyWithdraw() public override nonReentrant {
        uint256 amount = _balances[msg.sender];
        require(amount > 0, "Cannot withdraw 0");
        _totalSupply = _totalSupply.sub(amount);
        _balances[msg.sender] = 0;
        rewards[msg.sender] = 0;
        TransferHelper.safeTransfer(stakingToken, msg.sender, amount);
        emit EmergencyWithdraw(msg.sender, amount);
    }

    function getReward() public override nonReentrant updateReward(msg.sender) {
        uint256 reward = rewards[msg.sender];
        if (reward > 0) {
            rewards[msg.sender] = 0;
            // WETH balance decreased after this
            uint256 transferred = _safeWETHTransfer(msg.sender, reward);
            // must refresh WETH balance record after updating WETH balance
            // or lastUpdateRewardsTokenBalance could be less than the newest WETH balance in the next update
            lastUpdateRewardsTokenBalance = IWETH(rewardsToken).balanceOf(address(this));
            emit RewardPaid(msg.sender, transferred);
        }
    }

    function addETHReward() external payable override { // no need to update reward here
        IWETH(rewardsToken).deposit{value: msg.value}(); // support for sending ETH for rewards
    }

    function exit() external override {
        withdraw(_balances[msg.sender]);
        getReward();
    }

    function setGovernance(address _new) external {
        require(msg.sender == governance, "CoFiStaking: !governance");
        governance = _new;
    }

    function setDividendShare(uint256 share) external {
        require(msg.sender == governance, "CoFiStaking: !governance");
        require(share <= 100, "CoFiStaking: invalid share setting");
        dividendShare = share;
    }

    function withdrawSavingByGov(address _to, uint256 _amount) external nonReentrant {
        require(msg.sender == governance, "CoFiStaking: !governance");
        pendingSavingAmount = pendingSavingAmount.sub(_amount);
        IWETH(rewardsToken).withdraw(_amount);
        TransferHelper.safeTransferETH(_to, _amount);
        // must refresh WETH balance record after updating WETH balance
        // or lastUpdateRewardsTokenBalance could be less than the newest WETH balance in the next update
        lastUpdateRewardsTokenBalance = IWETH(rewardsToken).balanceOf(address(this));
        emit SavingWithdrawn(_to, _amount);
    }

    // Safe WETH transfer function, just in case if rounding error or ending of mining causes pool to not have enough WETHs.
    function _safeWETHTransfer(address _to, uint256 _amount) internal returns (uint256) {
        uint256 bal = IWETH(rewardsToken).balanceOf(address(this));
        if (_amount > bal) {
            _amount = bal;
        }
        // convert WETH to ETH, and send to `_to`
        IWETH(rewardsToken).withdraw(_amount);
        TransferHelper.safeTransferETH(_to, _amount);
        return _amount;
    }

    /* ========== MODIFIERS ========== */

    modifier updateReward(address account) {
        (uint256 _rewardPerToken, uint256 _accrued) = _rewardPerTokenAndAccrued();
        rewardPerTokenStored = _rewardPerToken;
        if (_accrued > 0) {
            uint256 newSaving = _accrued.sub(_accrued.mul(dividendShare).div(100)); // left 80%
            pendingSavingAmount = pendingSavingAmount.add(newSaving);
        }
        // means it's the first update
        // add this check to ensure the WETH transferred in before the first user stake in, could be distributed in the next update
        if (_totalSupply != 0) { // we can use _accrued here too
            lastUpdateRewardsTokenBalance = IWETH(rewardsToken).balanceOf(address(this));
        }
        if (account != address(0)) {
            rewards[account] = earned(account);
            userRewardPerTokenPaid[account] = rewardPerTokenStored;
        }
        _;
    }

    /* ========== EVENTS ========== */

    event RewardAdded(address sender, uint256 reward);
    event Staked(address indexed user, uint256 amount);
    event StakedForOther(address indexed user, address indexed other, uint256 amount);
    event Withdrawn(address indexed user, uint256 amount);
    event SavingWithdrawn(address indexed to, uint256 amount);
    event EmergencyWithdraw(address indexed user, uint256 amount);
    event RewardPaid(address indexed user, uint256 reward);
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"address","name":"_stakingToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"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":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SavingWithdrawn","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":true,"internalType":"address","name":"other","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakedForOther","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":[],"name":"accrued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"addETHReward","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dividendShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateRewardsTokenBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingSavingAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"share","type":"uint256"}],"name":"setDividendShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_new","type":"address"}],"name":"setGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"other","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stakeForOther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawSavingByGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c0604052601460025534801561001557600080fd5b5060405161215c38038061215c8339818101604052604081101561003857600080fd5b508051602090910151600160008190556001600160601b0319606093841b81166080529190921b1660a05280546001600160a01b0319163317905560805160601c60a05160601c6120756100e7600039806107b15280610b7d5280610ea5528061111352806116fe52508061065f528061090752806109f85280610ad75280610bb65280610d535280611000528061135052806113f2528061159e5280611ac55280611b6c52506120756000f3fe60806040526004361061018e5760003560e01c8063a694fc3a116100d6578063df136d651161007f578063f20ffed711610059578063f20ffed714610436578063f56c7edc14610460578063fe72bd011461049957610195565b8063df136d65146103f7578063dfef9a361461040c578063e9fad8ee1461042157610195565b8063cd3daf9d116100b0578063cd3daf9d146103b8578063d1af0c7d146103cd578063db2e21bc146103e257610195565b8063a694fc3a14610346578063ab033ea914610370578063b42f8fc3146103a357610195565b80635aa6e6751161013857806372f702f31161011257806372f702f3146102e95780638b876347146102fe578063a07e52a21461033157610195565b80635aa6e675146102705780636a0b91a5146102a157806370a08231146102b657610195565b80632e1a7d4d116101695780632e1a7d4d146102275780633d18b9121461025357806341f894ff1461026857610195565b80628cc2621461019a5780630700037d146101df57806318160ddd1461021257610195565b3661019557005b600080fd5b3480156101a657600080fd5b506101cd600480360360208110156101bd57600080fd5b50356001600160a01b03166104d2565b60408051918252519081900360200190f35b3480156101eb57600080fd5b506101cd6004803603602081101561020257600080fd5b50356001600160a01b0316610550565b34801561021e57600080fd5b506101cd610562565b34801561023357600080fd5b506102516004803603602081101561024a57600080fd5b5035610569565b005b34801561025f57600080fd5b50610251610818565b610251610ad5565b34801561027c57600080fd5b50610285610b4b565b604080516001600160a01b039092168252519081900360200190f35b3480156102ad57600080fd5b506101cd610b5a565b3480156102c257600080fd5b506101cd600480360360208110156102d957600080fd5b50356001600160a01b0316610b60565b3480156102f557600080fd5b50610285610b7b565b34801561030a57600080fd5b506101cd6004803603602081101561032157600080fd5b50356001600160a01b0316610b9f565b34801561033d57600080fd5b506101cd610bb1565b34801561035257600080fd5b506102516004803603602081101561036957600080fd5b5035610c64565b34801561037c57600080fd5b506102516004803603602081101561039357600080fd5b50356001600160a01b0316610f0d565b3480156103af57600080fd5b506101cd610fa6565b3480156103c457600080fd5b506101cd610fac565b3480156103d957600080fd5b50610285610ffe565b3480156103ee57600080fd5b50610251611022565b34801561040357600080fd5b506101cd611177565b34801561041857600080fd5b506101cd61117d565b34801561042d57600080fd5b50610251611183565b34801561044257600080fd5b506102516004803603602081101561045957600080fd5b50356111a6565b34801561046c57600080fd5b506102516004803603604081101561048357600080fd5b506001600160a01b03813516906020013561124a565b3480156104a557600080fd5b50610251600480360360408110156104bc57600080fd5b506001600160a01b0381351690602001356114af565b6001600160a01b038116600090815260076020908152604080832054600690925282205461054a919061054490670de0b6b3a76400009061053e9061051f90610519610fac565b90611771565b6001600160a01b038816600090815260096020526040902054906117ba565b90611813565b90611855565b92915050565b60076020526000908152604090205481565b6008545b90565b600260005414156105c1576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260009081553390806105d36118af565b60058290559092509050801561061e576000610609610602606461053e600254866117ba90919063ffffffff16565b8390611771565b6003549091506106199082611855565b600355505b600854156106d557604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a08231916024808301926020929190829003018186803b1580156106a557600080fd5b505afa1580156106b9573d6000803e3d6000fd5b505050506040513d60208110156106cf57600080fd5b50516004555b6001600160a01b03831615610719576106ed836104d2565b6001600160a01b0384166000908152600760209081526040808320939093556005546006909152919020555b6000841161076e576040805162461bcd60e51b815260206004820152601160248201527f43616e6e6f742077697468647261772030000000000000000000000000000000604482015290519081900360640190fd5b60085461077b9085611771565b600855336000908152600960205260409020546107989085611771565b336000818152600960205260409020919091556107d7907f00000000000000000000000000000000000000000000000000000000000000009086611911565b60408051858152905133917f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5919081900360200190a2505060016000555050565b60026000541415610870576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260009081553390806108826118af565b6005829055909250905080156108c65760006108b1610602606461053e600254866117ba90919063ffffffff16565b6003549091506108c19082611855565b600355505b6008541561097d57604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a08231916024808301926020929190829003018186803b15801561094d57600080fd5b505afa158015610961573d6000803e3d6000fd5b505050506040513d602081101561097757600080fd5b50516004555b6001600160a01b038316156109c157610995836104d2565b6001600160a01b0384166000908152600760209081526040808320939093556005546006909152919020555b336000908152600760205260409020548015610aca57336000818152600760205260408120819055906109f49083611ac0565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610a6357600080fd5b505afa158015610a77573d6000803e3d6000fd5b505050506040513d6020811015610a8d57600080fd5b505160045560408051828152905133917fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486919081900360200190a2505b505060016000555050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b3057600080fd5b505af1158015610b44573d6000803e3d6000fd5b5050505050565b6001546001600160a01b031681565b60045481565b6001600160a01b031660009081526009602052604090205490565b7f000000000000000000000000000000000000000000000000000000000000000081565b60066020526000908152604090205481565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610c2157600080fd5b505afa158015610c35573d6000803e3d6000fd5b505050506040513d6020811015610c4b57600080fd5b5051600454909150610c5e908290611771565b91505090565b60026000541415610cbc576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000908155339080610cce6118af565b600582905590925090508015610d12576000610cfd610602606461053e600254866117ba90919063ffffffff16565b600354909150610d0d9082611855565b600355505b60085415610dc957604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a08231916024808301926020929190829003018186803b158015610d9957600080fd5b505afa158015610dad573d6000803e3d6000fd5b505050506040513d6020811015610dc357600080fd5b50516004555b6001600160a01b03831615610e0d57610de1836104d2565b6001600160a01b0384166000908152600760209081526040808320939093556005546006909152919020555b60008411610e62576040805162461bcd60e51b815260206004820152600e60248201527f43616e6e6f74207374616b652030000000000000000000000000000000000000604482015290519081900360640190fd5b600854610e6f9085611855565b60085533600090815260096020526040902054610e8c9085611855565b33600081815260096020526040902091909155610ecc907f0000000000000000000000000000000000000000000000000000000000000000903087611bfa565b60408051858152905133917f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d919081900360200190a2505060016000555050565b6001546001600160a01b03163314610f6c576040805162461bcd60e51b815260206004820152601860248201527f436f46695374616b696e673a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b60025481565b600060085460001415610fc25750600554610566565b610ff9610ff0606461053e60085461053e600254610fea670de0b6b3a7640000610fea610bb1565b906117ba565b60055490611855565b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b6002600054141561107a576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600090815533815260096020526040902054806110e0576040805162461bcd60e51b815260206004820152601160248201527f43616e6e6f742077697468647261772030000000000000000000000000000000604482015290519081900360640190fd5b6008546110ed9082611771565b6008553360008181526009602090815260408083208390556007909152812055611139907f00000000000000000000000000000000000000000000000000000000000000009083611911565b60408051828152905133917f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd9695919081900360200190a2506001600055565b60055481565b60035481565b3360009081526009602052604090205461119c90610569565b6111a4610818565b565b6001546001600160a01b03163314611205576040805162461bcd60e51b815260206004820152601860248201527f436f46695374616b696e673a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b60648111156112455760405162461bcd60e51b8152600401808060200182810382526022815260200180611fb66022913960400191505060405180910390fd5b600255565b600260005414156112a2576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556001546001600160a01b03163314611306576040805162461bcd60e51b815260206004820152601860248201527f436f46695374616b696e673a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b6003546113139082611771565b600355604080517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810183905290516001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691632e1a7d4d91602480830192600092919082900301818387803b15801561139757600080fd5b505af11580156113ab573d6000803e3d6000fd5b505050506113b98282611da3565b604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a08231916024808301926020929190829003018186803b15801561143857600080fd5b505afa15801561144c573d6000803e3d6000fd5b505050506040513d602081101561146257600080fd5b50516004556040805182815290516001600160a01b038416917f87c374851ba88ebd02719e2b592fa23c658562900e426a6ecd9ad152addbb018919081900360200190a250506001600055565b60026000541415611507576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260009081558290806115196118af565b60058290559092509050801561155d576000611548610602606461053e600254866117ba90919063ffffffff16565b6003549091506115589082611855565b600355505b6008541561161457604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a08231916024808301926020929190829003018186803b1580156115e457600080fd5b505afa1580156115f8573d6000803e3d6000fd5b505050506040513d602081101561160e57600080fd5b50516004555b6001600160a01b038316156116585761162c836104d2565b6001600160a01b0384166000908152600760209081526040808320939093556005546006909152919020555b600084116116ad576040805162461bcd60e51b815260206004820152600e60248201527f43616e6e6f74207374616b652030000000000000000000000000000000000000604482015290519081900360640190fd5b6008546116ba9085611855565b6008556001600160a01b0385166000908152600960205260409020546116e09085611855565b6001600160a01b0386166000908152600960205260409020556117257f0000000000000000000000000000000000000000000000000000000000000000333087611bfa565b6040805185815290516001600160a01b0387169133917ff6709c821eb43e8e9953ad8ac910b4591a380ae9f014d75ce7d7a2a34299e0ef9181900360200190a350506001600055505050565b60006117b383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611eb9565b9392505050565b6000826117c95750600061054a565b828202828482816117d657fe5b04146117b35760405162461bcd60e51b8152600401808060200182810382526021815260200180611fd86021913960400191505060405180910390fd5b60006117b383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611f50565b6000828201838110156117b3576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600080600854600014156118c9575050600554600061190d565b60006118d3610bb1565b90506000611906610ff0606461053e60085461053e600254610fea670de0b6b3a76400008a6117ba90919063ffffffff16565b9350909150505b9091565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000178152925182516000946060949389169392918291908083835b602083106119da57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161199d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611a3c576040519150601f19603f3d011682016040523d82523d6000602084013e611a41565b606091505b5091509150818015611a6f575080511580611a6f5750808060200190516020811015611a6c57600080fd5b50515b610b44576040805162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604482015290519081900360640190fd5b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611b3057600080fd5b505afa158015611b44573d6000803e3d6000fd5b505050506040513d6020811015611b5a57600080fd5b5051905080831115611b6a578092505b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d846040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611bd057600080fd5b505af1158015611be4573d6000803e3d6000fd5b50505050611bf28484611da3565b509092915050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017815292518251600094606094938a169392918291908083835b60208310611ccb57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611c8e565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611d2d576040519150601f19603f3d011682016040523d82523d6000602084013e611d32565b606091505b5091509150818015611d60575080511580611d605750808060200190516020811015611d5d57600080fd5b50515b611d9b5760405162461bcd60e51b815260040180806020018281038252602481526020018061201c6024913960400191505060405180910390fd5b505050505050565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b60208310611e0d57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611dd0565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611e6f576040519150601f19603f3d011682016040523d82523d6000602084013e611e74565b606091505b5050905080611eb45760405162461bcd60e51b8152600401808060200182810382526023815260200180611ff96023913960400191505060405180910390fd5b505050565b60008184841115611f485760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611f0d578181015183820152602001611ef5565b50505050905090810190601f168015611f3a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183611f9f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611f0d578181015183820152602001611ef5565b506000838581611fab57fe5b049594505050505056fe436f46695374616b696e673a20696e76616c69642073686172652073657474696e67536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775472616e7366657248656c7065723a204554485f5452414e534645525f4641494c45445472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c4544a264697066735822122034462dcbbb3f4986c8a3fd0c9fec22df21655a337fc37fe180f721e02201d93264736f6c634300060c0033000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000001a23a6bfbadb59fa563008c0fb7cf96dfcf34ea1

Deployed Bytecode

0x60806040526004361061018e5760003560e01c8063a694fc3a116100d6578063df136d651161007f578063f20ffed711610059578063f20ffed714610436578063f56c7edc14610460578063fe72bd011461049957610195565b8063df136d65146103f7578063dfef9a361461040c578063e9fad8ee1461042157610195565b8063cd3daf9d116100b0578063cd3daf9d146103b8578063d1af0c7d146103cd578063db2e21bc146103e257610195565b8063a694fc3a14610346578063ab033ea914610370578063b42f8fc3146103a357610195565b80635aa6e6751161013857806372f702f31161011257806372f702f3146102e95780638b876347146102fe578063a07e52a21461033157610195565b80635aa6e675146102705780636a0b91a5146102a157806370a08231146102b657610195565b80632e1a7d4d116101695780632e1a7d4d146102275780633d18b9121461025357806341f894ff1461026857610195565b80628cc2621461019a5780630700037d146101df57806318160ddd1461021257610195565b3661019557005b600080fd5b3480156101a657600080fd5b506101cd600480360360208110156101bd57600080fd5b50356001600160a01b03166104d2565b60408051918252519081900360200190f35b3480156101eb57600080fd5b506101cd6004803603602081101561020257600080fd5b50356001600160a01b0316610550565b34801561021e57600080fd5b506101cd610562565b34801561023357600080fd5b506102516004803603602081101561024a57600080fd5b5035610569565b005b34801561025f57600080fd5b50610251610818565b610251610ad5565b34801561027c57600080fd5b50610285610b4b565b604080516001600160a01b039092168252519081900360200190f35b3480156102ad57600080fd5b506101cd610b5a565b3480156102c257600080fd5b506101cd600480360360208110156102d957600080fd5b50356001600160a01b0316610b60565b3480156102f557600080fd5b50610285610b7b565b34801561030a57600080fd5b506101cd6004803603602081101561032157600080fd5b50356001600160a01b0316610b9f565b34801561033d57600080fd5b506101cd610bb1565b34801561035257600080fd5b506102516004803603602081101561036957600080fd5b5035610c64565b34801561037c57600080fd5b506102516004803603602081101561039357600080fd5b50356001600160a01b0316610f0d565b3480156103af57600080fd5b506101cd610fa6565b3480156103c457600080fd5b506101cd610fac565b3480156103d957600080fd5b50610285610ffe565b3480156103ee57600080fd5b50610251611022565b34801561040357600080fd5b506101cd611177565b34801561041857600080fd5b506101cd61117d565b34801561042d57600080fd5b50610251611183565b34801561044257600080fd5b506102516004803603602081101561045957600080fd5b50356111a6565b34801561046c57600080fd5b506102516004803603604081101561048357600080fd5b506001600160a01b03813516906020013561124a565b3480156104a557600080fd5b50610251600480360360408110156104bc57600080fd5b506001600160a01b0381351690602001356114af565b6001600160a01b038116600090815260076020908152604080832054600690925282205461054a919061054490670de0b6b3a76400009061053e9061051f90610519610fac565b90611771565b6001600160a01b038816600090815260096020526040902054906117ba565b90611813565b90611855565b92915050565b60076020526000908152604090205481565b6008545b90565b600260005414156105c1576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260009081553390806105d36118af565b60058290559092509050801561061e576000610609610602606461053e600254866117ba90919063ffffffff16565b8390611771565b6003549091506106199082611855565b600355505b600854156106d557604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290516001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216916370a08231916024808301926020929190829003018186803b1580156106a557600080fd5b505afa1580156106b9573d6000803e3d6000fd5b505050506040513d60208110156106cf57600080fd5b50516004555b6001600160a01b03831615610719576106ed836104d2565b6001600160a01b0384166000908152600760209081526040808320939093556005546006909152919020555b6000841161076e576040805162461bcd60e51b815260206004820152601160248201527f43616e6e6f742077697468647261772030000000000000000000000000000000604482015290519081900360640190fd5b60085461077b9085611771565b600855336000908152600960205260409020546107989085611771565b336000818152600960205260409020919091556107d7907f0000000000000000000000001a23a6bfbadb59fa563008c0fb7cf96dfcf34ea19086611911565b60408051858152905133917f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5919081900360200190a2505060016000555050565b60026000541415610870576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260009081553390806108826118af565b6005829055909250905080156108c65760006108b1610602606461053e600254866117ba90919063ffffffff16565b6003549091506108c19082611855565b600355505b6008541561097d57604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290516001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216916370a08231916024808301926020929190829003018186803b15801561094d57600080fd5b505afa158015610961573d6000803e3d6000fd5b505050506040513d602081101561097757600080fd5b50516004555b6001600160a01b038316156109c157610995836104d2565b6001600160a01b0384166000908152600760209081526040808320939093556005546006909152919020555b336000908152600760205260409020548015610aca57336000818152600760205260408120819055906109f49083611ac0565b90507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610a6357600080fd5b505afa158015610a77573d6000803e3d6000fd5b505050506040513d6020811015610a8d57600080fd5b505160045560408051828152905133917fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486919081900360200190a2505b505060016000555050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610b3057600080fd5b505af1158015610b44573d6000803e3d6000fd5b5050505050565b6001546001600160a01b031681565b60045481565b6001600160a01b031660009081526009602052604090205490565b7f0000000000000000000000001a23a6bfbadb59fa563008c0fb7cf96dfcf34ea181565b60066020526000908152604090205481565b6000807f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610c2157600080fd5b505afa158015610c35573d6000803e3d6000fd5b505050506040513d6020811015610c4b57600080fd5b5051600454909150610c5e908290611771565b91505090565b60026000541415610cbc576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000908155339080610cce6118af565b600582905590925090508015610d12576000610cfd610602606461053e600254866117ba90919063ffffffff16565b600354909150610d0d9082611855565b600355505b60085415610dc957604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290516001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216916370a08231916024808301926020929190829003018186803b158015610d9957600080fd5b505afa158015610dad573d6000803e3d6000fd5b505050506040513d6020811015610dc357600080fd5b50516004555b6001600160a01b03831615610e0d57610de1836104d2565b6001600160a01b0384166000908152600760209081526040808320939093556005546006909152919020555b60008411610e62576040805162461bcd60e51b815260206004820152600e60248201527f43616e6e6f74207374616b652030000000000000000000000000000000000000604482015290519081900360640190fd5b600854610e6f9085611855565b60085533600090815260096020526040902054610e8c9085611855565b33600081815260096020526040902091909155610ecc907f0000000000000000000000001a23a6bfbadb59fa563008c0fb7cf96dfcf34ea1903087611bfa565b60408051858152905133917f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d919081900360200190a2505060016000555050565b6001546001600160a01b03163314610f6c576040805162461bcd60e51b815260206004820152601860248201527f436f46695374616b696e673a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b60025481565b600060085460001415610fc25750600554610566565b610ff9610ff0606461053e60085461053e600254610fea670de0b6b3a7640000610fea610bb1565b906117ba565b60055490611855565b905090565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6002600054141561107a576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600090815533815260096020526040902054806110e0576040805162461bcd60e51b815260206004820152601160248201527f43616e6e6f742077697468647261772030000000000000000000000000000000604482015290519081900360640190fd5b6008546110ed9082611771565b6008553360008181526009602090815260408083208390556007909152812055611139907f0000000000000000000000001a23a6bfbadb59fa563008c0fb7cf96dfcf34ea19083611911565b60408051828152905133917f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd9695919081900360200190a2506001600055565b60055481565b60035481565b3360009081526009602052604090205461119c90610569565b6111a4610818565b565b6001546001600160a01b03163314611205576040805162461bcd60e51b815260206004820152601860248201527f436f46695374616b696e673a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b60648111156112455760405162461bcd60e51b8152600401808060200182810382526022815260200180611fb66022913960400191505060405180910390fd5b600255565b600260005414156112a2576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556001546001600160a01b03163314611306576040805162461bcd60e51b815260206004820152601860248201527f436f46695374616b696e673a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b6003546113139082611771565b600355604080517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810183905290516001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21691632e1a7d4d91602480830192600092919082900301818387803b15801561139757600080fd5b505af11580156113ab573d6000803e3d6000fd5b505050506113b98282611da3565b604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290516001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216916370a08231916024808301926020929190829003018186803b15801561143857600080fd5b505afa15801561144c573d6000803e3d6000fd5b505050506040513d602081101561146257600080fd5b50516004556040805182815290516001600160a01b038416917f87c374851ba88ebd02719e2b592fa23c658562900e426a6ecd9ad152addbb018919081900360200190a250506001600055565b60026000541415611507576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260009081558290806115196118af565b60058290559092509050801561155d576000611548610602606461053e600254866117ba90919063ffffffff16565b6003549091506115589082611855565b600355505b6008541561161457604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290516001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216916370a08231916024808301926020929190829003018186803b1580156115e457600080fd5b505afa1580156115f8573d6000803e3d6000fd5b505050506040513d602081101561160e57600080fd5b50516004555b6001600160a01b038316156116585761162c836104d2565b6001600160a01b0384166000908152600760209081526040808320939093556005546006909152919020555b600084116116ad576040805162461bcd60e51b815260206004820152600e60248201527f43616e6e6f74207374616b652030000000000000000000000000000000000000604482015290519081900360640190fd5b6008546116ba9085611855565b6008556001600160a01b0385166000908152600960205260409020546116e09085611855565b6001600160a01b0386166000908152600960205260409020556117257f0000000000000000000000001a23a6bfbadb59fa563008c0fb7cf96dfcf34ea1333087611bfa565b6040805185815290516001600160a01b0387169133917ff6709c821eb43e8e9953ad8ac910b4591a380ae9f014d75ce7d7a2a34299e0ef9181900360200190a350506001600055505050565b60006117b383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611eb9565b9392505050565b6000826117c95750600061054a565b828202828482816117d657fe5b04146117b35760405162461bcd60e51b8152600401808060200182810382526021815260200180611fd86021913960400191505060405180910390fd5b60006117b383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611f50565b6000828201838110156117b3576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600080600854600014156118c9575050600554600061190d565b60006118d3610bb1565b90506000611906610ff0606461053e60085461053e600254610fea670de0b6b3a76400008a6117ba90919063ffffffff16565b9350909150505b9091565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000178152925182516000946060949389169392918291908083835b602083106119da57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161199d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611a3c576040519150601f19603f3d011682016040523d82523d6000602084013e611a41565b606091505b5091509150818015611a6f575080511580611a6f5750808060200190516020811015611a6c57600080fd5b50515b610b44576040805162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604482015290519081900360640190fd5b6000807f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611b3057600080fd5b505afa158015611b44573d6000803e3d6000fd5b505050506040513d6020811015611b5a57600080fd5b5051905080831115611b6a578092505b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316632e1a7d4d846040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611bd057600080fd5b505af1158015611be4573d6000803e3d6000fd5b50505050611bf28484611da3565b509092915050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017815292518251600094606094938a169392918291908083835b60208310611ccb57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611c8e565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611d2d576040519150601f19603f3d011682016040523d82523d6000602084013e611d32565b606091505b5091509150818015611d60575080511580611d605750808060200190516020811015611d5d57600080fd5b50515b611d9b5760405162461bcd60e51b815260040180806020018281038252602481526020018061201c6024913960400191505060405180910390fd5b505050505050565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b60208310611e0d57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611dd0565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611e6f576040519150601f19603f3d011682016040523d82523d6000602084013e611e74565b606091505b5050905080611eb45760405162461bcd60e51b8152600401808060200182810382526023815260200180611ff96023913960400191505060405180910390fd5b505050565b60008184841115611f485760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611f0d578181015183820152602001611ef5565b50505050905090810190601f168015611f3a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183611f9f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611f0d578181015183820152602001611ef5565b506000838581611fab57fe5b049594505050505056fe436f46695374616b696e673a20696e76616c69642073686172652073657474696e67536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775472616e7366657248656c7065723a204554485f5452414e534645525f4641494c45445472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c4544a264697066735822122034462dcbbb3f4986c8a3fd0c9fec22df21655a337fc37fe180f721e02201d93264736f6c634300060c0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000001a23a6bfbadb59fa563008c0fb7cf96dfcf34ea1

-----Decoded View---------------
Arg [0] : _rewardsToken (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [1] : _stakingToken (address): 0x1a23a6BfBAdB59fa563008c0fB7cf96dfCF34Ea1

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [1] : 0000000000000000000000001a23a6bfbadb59fa563008c0fb7cf96dfcf34ea1


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ 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.