Contract 0xe59988d947f80b59ff1de7bd413e5e5517906cb2

Txn Hash Method
Block
From
To
Value [Txn Fee]
0xd095a45c9e6bc639dbdfe548929e7ddbbf5f38b216e0d789639a3ed6413b61b4Become Implement...53864342021-10-08 20:16:06225 days 10 hrs ago0x319ce476176de7fb8f55d0319d2efcb85e12c7af IN 0xe59988d947f80b59ff1de7bd413e5e5517906cb20 AVAX0.00094767525
0xdb9cd0b836eb049cfb4504e06930aaea2d745e523074615d721b99e87586fe080x6080604053807562021-10-08 17:03:30225 days 14 hrs ago0x5423819b3b5bb38b0e9e9e59f22f9034e2d8819b IN  Create: PglStakingContract0 AVAX0.03182475 25
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PglStakingContract

Compiler Version
v0.5.17+commit.d19bba13

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at snowtrace.io on 2021-11-02
*/

/**
 * File: ReentrancyGuard.sol
 */

// SPDX-License-Identifier: MIT

pragma solidity 0.5.17;

/**
 * @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() public {
        _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;
    }
}


/**
 * File: EIP20Interface.sol
 */

pragma solidity 0.5.17;

/**
 * @title ERC 20 Token Standard Interface
 *  https://eips.ethereum.org/EIPS/eip-20
 */
interface EIP20Interface {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);

    /**
      * @notice Get the total number of tokens in circulation
      * @return The supply of tokens
      */
    function totalSupply() external view returns (uint256);

    /**
     * @notice Gets the balance of the specified address
     * @param owner The address from which the balance will be retrieved
     * @return The balance
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
      * @notice Transfer `amount` tokens from `msg.sender` to `dst`
      * @param dst The address of the destination account
      * @param amount The number of tokens to transfer
      * @return Whether or not the transfer succeeded
      */
    function transfer(address dst, uint256 amount) external returns (bool success);

    /**
      * @notice Transfer `amount` tokens from `src` to `dst`
      * @param src The address of the source account
      * @param dst The address of the destination account
      * @param amount The number of tokens to transfer
      * @return Whether or not the transfer succeeded
      */
    function transferFrom(address src, address dst, uint256 amount) external returns (bool success);

    /**
      * @notice Approve `spender` to transfer up to `amount` from `src`
      * @dev This will overwrite the approval amount for `spender`
      *  and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)
      * @param spender The address of the account which may transfer tokens
      * @param amount The number of tokens that are approved (-1 means infinite)
      * @return Whether or not the approval succeeded
      */
    function approve(address spender, uint256 amount) external returns (bool success);

    /**
      * @notice Get the current allowance from `owner` for `spender`
      * @param owner The address of the account which owns the tokens to be spent
      * @param spender The address of the account which may transfer tokens
      * @return The number of tokens allowed to be spent (-1 means infinite)
      */
    function allowance(address owner, address spender) external view returns (uint256 remaining);

    event Transfer(address indexed from, address indexed to, uint256 amount);
    event Approval(address indexed owner, address indexed spender, uint256 amount);
}


/**
 * File: SafeMath.sol
 */

pragma solidity 0.5.17;

// From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/Math.sol
// Subject to the MIT license.

/**
 * @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 addition of two unsigned integers, reverting with custom message on overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, errorMessage);

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on underflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot underflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction underflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on underflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot underflow.
     */
    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 multiplication of two unsigned integers, reverting on overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b, string memory errorMessage) 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, errorMessage);

        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) {
        // Solidity only automatically asserts when dividing by 0
        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;
    }
}


/**
 * File: PglStakingContractProxyStorage.sol
 */

pragma solidity 0.5.17;


contract PglStakingContractProxyStorage {
    // Current contract admin address
    address public admin;

    // Requested new admin for the contract
    address public pendingAdmin;

    // Current contract implementation address
    address public implementation;

    // Requested new contract implementation address
    address public pendingImplementation;
}


/**
 * File: PglStakingContractStorage.sol
 */

pragma solidity 0.5.17;



contract PglStakingContractStorage is PglStakingContractProxyStorage {
    uint constant nofStakingRewards = 2;
    uint constant REWARD_AVAX = 0;
    uint constant REWARD_QI = 1;

    // QI-AVAX PGL token contract address
    address public pglTokenAddress;

    // Addresses of the ERC20 reward tokens
    mapping(uint => address) public rewardTokenAddresses;

    // Reward accrual speeds per reward token as tokens per second
    mapping(uint => uint) public rewardSpeeds;

    // Unclaimed staking rewards per user and token
    mapping(address => mapping(uint => uint)) public accruedReward;

    // Supplied PGL tokens per user
    mapping(address => uint) public supplyAmount;

    // Sum of all supplied PGL tokens
    uint public totalSupplies;

    /*
     * rewardIndex keeps track of the total amount of rewards to be distributed for
     * each supplied unit of PGL tokens. When used together with supplierIndex,
     * the total amount of rewards to be paid out to individual users can be calculated
     * when the user claims their rewards.
     *
     * Consider the following:
     *
     * At contract deployment, the contract has a zero PGL balance. Immediately, a new
     * user, User A, deposits 1000 PGL tokens, thus increasing the total supply to
     * 1000 PGL. After 60 seconds, a second user, User B, deposits an additional 500 PGL,
     * increasing the total supplied amount to 1500 PGL.
     *
     * Because all balance-changing contract calls, as well as those changing the reward
     * speeds, must invoke the accrueRewards function, these deposit calls trigger the
     * function too. The accrueRewards function considers the reward speed (denoted in
     * reward tokens per second), the reward and supplier reward indexes, and the supply
     * balance to calculate the accrued rewards.
     *
     * When User A deposits their tokens, rewards are yet to be accrued due to previous
     * inactivity; the elapsed time since the previous, non-existent, reward-accruing
     * contract call is zero, thus having a reward accrual period of zero. The block
     * time of the deposit transaction is saved in the contract to indicate last
     * activity time.
     *
     * When User B deposits their tokens, 60 seconds has elapsed since the previous
     * call to the accrueRewards function, indicated by the difference of the current
     * block time and the last activity time. In other words, up till the time of
     * User B's deposit, the contract has had a 60 second accrual period for the total
     * amount of 1000 PGL tokens at the set reward speed. Assuming a reward speed of
     * 5 tokens per second (denoted 5 T/s), the accrueRewards function calculates the
     * accrued reward per supplied unit of PGL tokens for the elapsed time period.
     * This works out to ((5 T/s) / 1000 PGL) * 60 s = 0.3 T/PGL during the 60 second
     * period. At this point, the global reward index variable is updated, increasing
     * its value by 0.3 T/PGL, and the reward accrual block timestamp,
     * initialised in the previous step, is updated.
     *
     * After 90 seconds of the contract deployment, User A decides to claim their accrued
     * rewards. Claiming affects token balances, thus requiring an invocation of the
     * accrueRewards function. This time, the accrual period is 30 seconds (90 s - 60 s),
     * for which the reward accrued per unit of PGL is ((5 T/s) / 1500 PGL) * 30 s = 0.1 T/PGL.
     * The reward index is updated to 0.4 T/PGL (0.3 T/PGL + 0.1 T/PGL) and the reward
     * accrual block timestamp is set to the current block time.
     *
     * After the reward accrual, User A's rewards are claimed by transferring the correct
     * amount of T tokens from the contract to User A. Because User A has not claimed any
     * rewards yet, their supplier index is zero, the initial value determined by the
     * global reward index at the time of the user's first deposit. The amount of accrued
     * rewards is determined by the difference between the global reward index and the
     * user's own supplier index; essentially, this value represents the amount of
     * T tokens that have been accrued per supplied PGL during the time since the user's
     * last claim. User A has a supply balance of 1000 PGL, thus having an unclaimed
     * token amount of (0.4 T/PGL - 0 T/PGL) * 1000 PGL = 400 T. This amount is
     * transferred to User A, and their supplier index is set to the current global reward
     * index to indicate that all previous rewards have been accrued.
     *
     * If User B was to claim their rewards at the same time, the calculation would take
     * the form of (0.4 T/PGL - 0.3 T/PGL) * 500 PGL = 50 T. As expected, the total amount
     * of accrued reward (5 T/s * 90 s = 450 T) equals to the sum of the rewards paid
     * out to both User A and User B (400 T + 50 T = 450 T).
     *
     * This method of reward accrual is used to minimise the contract call complexity.
     * If a global mapping of users to their accrued rewards was implemented instead of
     * the index calculations, each function call invoking the accrueRewards function
     * would become immensely more expensive due to having to update the rewards for each
     * user. In contrast, the index approach allows the update of only a single user
     * while still keeping track of the other's rewards.
     *
     * Because rewards can be paid in multiple assets, reward indexes, reward supplier
     * indexes, and reward speeds depend on the StakingReward token.
     */
    mapping(uint => uint) public rewardIndex;
    mapping(address => mapping(uint => uint)) public supplierRewardIndex;
    uint public accrualBlockTimestamp;
}


/**
 * File: PglStakingContractProxy.sol
 */

pragma solidity 0.5.17;



contract PglStakingContractProxy is ReentrancyGuard, PglStakingContractProxyStorage {
    constructor() public {
        admin = msg.sender;
    }

    /**
     * Request a new admin to be set for the contract.
     *
     * @param newAdmin New admin address
     */
    function setPendingAdmin(address newAdmin) public adminOnly {
        pendingAdmin = newAdmin;
    }

    /**
     * Accept admin transfer from the current admin to the new.
     */
    function acceptPendingAdmin() public {
        require(msg.sender == pendingAdmin && pendingAdmin != address(0), "Caller must be the pending admin");

        admin = pendingAdmin;
        pendingAdmin = address(0);
    }

    /**
     * Request a new implementation to be set for the contract.
     *
     * @param newImplementation New contract implementation contract address
     */
    function setPendingImplementation(address newImplementation) public adminOnly {
        pendingImplementation = newImplementation;
    }

    /**
     * Accept pending implementation change
     */
    function acceptPendingImplementation() public {
        require(msg.sender == pendingImplementation && pendingImplementation != address(0), "Only the pending implementation contract can call this");

        implementation = pendingImplementation;
        pendingImplementation = address(0);
    }

    function () payable external {
        (bool success, ) = implementation.delegatecall(msg.data);

        assembly {
            let free_mem_ptr := mload(0x40)
            returndatacopy(free_mem_ptr, 0, returndatasize)

            switch success
            case 0 { revert(free_mem_ptr, returndatasize) }
            default { return(free_mem_ptr, returndatasize) }
        }
    }

    /********************************************************
     *                                                      *
     *                      MODIFIERS                       *
     *                                                      *
     ********************************************************/

    modifier adminOnly {
        require(msg.sender == admin, "admin only");
        _;
    }
}


/**
 * File: PglStakingContract.sol
 */

pragma solidity 0.5.17;



contract PglStakingContract is ReentrancyGuard, PglStakingContractStorage {
    using SafeMath for uint256;

    constructor() public {
        admin = msg.sender;
    }


    /********************************************************
     *                                                      *
     *                   PUBLIC FUNCTIONS                   *
     *                                                      *
     ********************************************************/

    /**
     * Deposit Pangolin QI-AVAX liquidity provider tokens into the staking contract.
     *
     * @param pglAmount The amount of PGL tokens to deposit
     */
    function deposit(uint pglAmount) external nonReentrant {
        require(pglTokenAddress != address(0), "PGL Token address can not be zero");

        EIP20Interface pglToken = EIP20Interface(pglTokenAddress);
        uint contractBalance = pglToken.balanceOf(address(this));
        pglToken.transferFrom(msg.sender, address(this), pglAmount);
        uint depositedAmount = pglToken.balanceOf(address(this)).sub(contractBalance);

        require(depositedAmount > 0, "Zero deposit");

        distributeReward(msg.sender);

        totalSupplies = totalSupplies.add(depositedAmount);
        supplyAmount[msg.sender] = supplyAmount[msg.sender].add(depositedAmount);
    }

    /**
     * Redeem deposited PGL tokens from the contract.
     *
     * @param pglAmount Redeem amount
     */
    function redeem(uint pglAmount) external nonReentrant {
        require(pglTokenAddress != address(0), "PGL Token address can not be zero");
        require(pglAmount <= supplyAmount[msg.sender], "Too large withdrawal");

        distributeReward(msg.sender);

        supplyAmount[msg.sender] = supplyAmount[msg.sender].sub(pglAmount);
        totalSupplies = totalSupplies.sub(pglAmount);

        EIP20Interface pglToken = EIP20Interface(pglTokenAddress);
        pglToken.transfer(msg.sender, pglAmount);
    }

    /**
     * Claim pending rewards from the staking contract by transferring them
     * to the requester.
     */
    function claimRewards() external nonReentrant {
        distributeReward(msg.sender);

        uint amount = accruedReward[msg.sender][REWARD_QI];
        claimErc20(REWARD_QI, msg.sender, amount);
    }

    /**
     * Get the current amount of available rewards for claiming.
     *
     * @param rewardToken Reward token whose claimable balance to query
     * @return Balance of claimable reward tokens
     */
    function getClaimableRewards(uint rewardToken) external view returns(uint) {
        require(rewardToken <= nofStakingRewards, "Invalid reward token");

        // Static reward value for AVAX due to erroneously emitted AVAX
        if (rewardToken == REWARD_AVAX) {
            return 0;
        }

        uint rewardIndexDelta = rewardIndex[rewardToken].sub(supplierRewardIndex[msg.sender][rewardToken]);
        uint claimableReward = rewardIndexDelta.mul(supplyAmount[msg.sender]).div(1e36).add(accruedReward[msg.sender][rewardToken]);

        return claimableReward;
    }

    /**
     * Fallback function to accept AVAX deposits.
     */
    function () external payable {}


    /********************************************************
     *                                                      *
     *               ADMIN-ONLY FUNCTIONS                   *
     *                                                      *
     ********************************************************/

    /**
     * Set reward distribution speed.
     *
     * @param rewardToken Reward token speed to change
     * @param speed New reward speed
     */
    function setRewardSpeed(uint rewardToken, uint speed) external adminOnly {
        if (accrualBlockTimestamp != 0) {
            accrueReward();
        }

        rewardSpeeds[rewardToken] = speed;
    }

    /**
     * Set ERC20 reward token contract address.
     *
     * @param rewardToken Reward token address to set
     * @param rewardTokenAddress New contract address
     */
    function setRewardTokenAddress(uint rewardToken, address rewardTokenAddress) external adminOnly {
        require(rewardToken != REWARD_AVAX, "Cannot set AVAX address");
        rewardTokenAddresses[rewardToken] = rewardTokenAddress;
    }

    /**
     * Set QI-AVAX PGL token contract address.
     *
     * @param newPglTokenAddress New QI-AVAX PGL token contract address
     */
    function setPglTokenAddress(address newPglTokenAddress) external adminOnly {
        pglTokenAddress = newPglTokenAddress;
    }

    /**
     * Accept this contract as the implementation for a proxy.
     *
     * @param proxy PglStakingContractProxy
     */
    function becomeImplementation(PglStakingContractProxy proxy) external {
        require(msg.sender == proxy.admin(), "Only proxy admin can change the implementation");
        proxy.acceptPendingImplementation();
    }


    /********************************************************
     *                                                      *
     *                  INTERNAL FUNCTIONS                  *
     *                                                      *
     ********************************************************/

    /**
     * Update reward accrual state.
     *
     * @dev accrueReward() must be called every time the token balances
     *      or reward speeds change
     */
    function accrueReward() internal {
        uint blockTimestampDelta = block.timestamp.sub(accrualBlockTimestamp);
        accrualBlockTimestamp = block.timestamp;

        if (blockTimestampDelta == 0 || totalSupplies == 0) {
            return;
        }

        for (uint i = 0; i < nofStakingRewards; i += 1) {
            uint rewardSpeed = rewardSpeeds[i];
            if (rewardSpeed == 0) {
                continue;
            }

            uint accrued = rewardSpeeds[i].mul(blockTimestampDelta);
            uint accruedPerPGL = accrued.mul(1e36).div(totalSupplies);

            rewardIndex[i] = rewardIndex[i].add(accruedPerPGL);
        }
    }

    /**
     * Calculate accrued rewards for a single account based on the reward indexes.
     *
     * @param recipient Account for which to calculate accrued rewards
     */
    function distributeReward(address recipient) internal {
        accrueReward();

        for (uint i = 0; i < nofStakingRewards; i += 1) {
            uint rewardIndexDelta = rewardIndex[i].sub(supplierRewardIndex[recipient][i]);
            uint accruedAmount = rewardIndexDelta.mul(supplyAmount[recipient]).div(1e36);
            accruedReward[recipient][i] = accruedReward[recipient][i].add(accruedAmount);
            supplierRewardIndex[recipient][i] = rewardIndex[i];
        }
    }

    /**
     * Transfer AVAX rewards from the contract to the reward recipient.
     *
     * @param recipient Address, whose AVAX rewards are claimed
     * @param amount The amount of claimed AVAX
     */
    function claimAvax(address payable recipient, uint amount) internal {
        require(accruedReward[recipient][REWARD_AVAX] <= amount, "Not enough accrued rewards");

        accruedReward[recipient][REWARD_AVAX] = accruedReward[recipient][REWARD_AVAX].sub(amount);
        recipient.transfer(amount);
    }

    /**
     * Transfer ERC20 rewards from the contract to the reward recipient.
     *
     * @param rewardToken ERC20 reward token which is claimed
     * @param recipient Address, whose rewards are claimed
     * @param amount The amount of claimed reward
     */
    function claimErc20(uint rewardToken, address recipient, uint amount) internal {
        require(rewardToken != REWARD_AVAX, "Cannot use claimErc20 for AVAX");
        require(accruedReward[recipient][rewardToken] <= amount, "Not enough accrued rewards");
        require(rewardTokenAddresses[rewardToken] != address(0), "reward token address can not be zero");

        EIP20Interface token = EIP20Interface(rewardTokenAddresses[rewardToken]);
        accruedReward[recipient][rewardToken] = accruedReward[recipient][rewardToken].sub(amount);
        token.transfer(recipient, amount);
    }


    /********************************************************
     *                                                      *
     *                      MODIFIERS                       *
     *                                                      *
     ********************************************************/

    modifier adminOnly {
        require(msg.sender == admin, "admin only");
        _;
    }
}

Contract ABI

[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"accrualBlockTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"accruedReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract PglStakingContractProxy","name":"proxy","type":"address"}],"name":"becomeImplementation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimRewards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"pglAmount","type":"uint256"}],"name":"deposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"rewardToken","type":"uint256"}],"name":"getClaimableRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pendingImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pglTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"pglAmount","type":"uint256"}],"name":"redeem","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardSpeeds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokenAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newPglTokenAddress","type":"address"}],"name":"setPglTokenAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"rewardToken","type":"uint256"},{"internalType":"uint256","name":"speed","type":"uint256"}],"name":"setRewardSpeed","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"rewardToken","type":"uint256"},{"internalType":"address","name":"rewardTokenAddress","type":"address"}],"name":"setRewardTokenAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"supplierRewardIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"supplyAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupplies","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b506001600081905580546001600160a01b03191633179055611544806100376000396000f3fe60806040526004361061012a5760003560e01c806392d8282f116100ab578063d068cdc51161006f578063d068cdc514610379578063db006a751461038e578063eaac8c32146103b8578063f495c9c9146103eb578063f75ddfa814610424578063f851a4401461045d5761012a565b806392d8282f146102c25780639c41f6ca146102d7578063b6b55f251461030a578063cfa9920114610334578063d03a7d25146103495761012a565b80635c60da1b116100f25780635c60da1b146101f65780636612313a1461020b5780637b167dfa146102355780637b2d9b2c1461025f57806384ae152d146102895761012a565b80631130a36c1461012c57806324cb2d9a14610171578063267822471461019b578063372500ab146101cc578063396f7b23146101e1575b005b34801561013857600080fd5b5061015f6004803603602081101561014f57600080fd5b50356001600160a01b0316610472565b60408051918252519081900360200190f35b34801561017d57600080fd5b5061015f6004803603602081101561019457600080fd5b5035610484565b3480156101a757600080fd5b506101b0610496565b604080516001600160a01b039092168252519081900360200190f35b3480156101d857600080fd5b5061012a6104a5565b3480156101ed57600080fd5b506101b061053c565b34801561020257600080fd5b506101b061054b565b34801561021757600080fd5b5061015f6004803603602081101561022e57600080fd5b503561055a565b34801561024157600080fd5b5061015f6004803603602081101561025857600080fd5b503561056c565b34801561026b57600080fd5b506101b06004803603602081101561028257600080fd5b5035610671565b34801561029557600080fd5b5061012a600480360360408110156102ac57600080fd5b50803590602001356001600160a01b031661068c565b3480156102ce57600080fd5b506101b0610758565b3480156102e357600080fd5b5061012a600480360360208110156102fa57600080fd5b50356001600160a01b0316610767565b34801561031657600080fd5b5061012a6004803603602081101561032d57600080fd5b50356107d5565b34801561034057600080fd5b5061015f610aa4565b34801561035557600080fd5b5061012a6004803603604081101561036c57600080fd5b5080359060200135610aaa565b34801561038557600080fd5b5061015f610b18565b34801561039a57600080fd5b5061012a600480360360208110156103b157600080fd5b5035610b1e565b3480156103c457600080fd5b5061012a600480360360208110156103db57600080fd5b50356001600160a01b0316610cf6565b3480156103f757600080fd5b5061015f6004803603604081101561040e57600080fd5b506001600160a01b038135169060200135610df7565b34801561043057600080fd5b5061015f6004803603604081101561044757600080fd5b506001600160a01b038135169060200135610e14565b34801561046957600080fd5b506101b0610e31565b60096020526000908152604090205481565b60076020526000908152604090205481565b6002546001600160a01b031681565b600260005414156104fd576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260005561050b33610e40565b336000818152600860209081526040808320600180855292529091205491610534919083610f5a565b506001600055565b6004546001600160a01b031681565b6003546001600160a01b031681565b600b6020526000908152604090205481565b600060028211156105bb576040805162461bcd60e51b815260206004820152601460248201527324b73b30b634b2103932bbb0b932103a37b5b2b760611b604482015290519081900360640190fd5b816105c85750600061066c565b336000908152600c60209081526040808320858452825280832054600b9092528220546105fa9163ffffffff61115a16565b336000818152600860209081526040808320888452825280832054938352600990915281205492935091610667919061065b906ec097ce7bc90715b34b9f10000000009061064f90879063ffffffff6111a516565b9063ffffffff6111fe16565b9063ffffffff61124016565b925050505b919050565b6006602052600090815260409020546001600160a01b031681565b6001546001600160a01b031633146106d8576040805162461bcd60e51b815260206004820152600a60248201526961646d696e206f6e6c7960b01b604482015290519081900360640190fd5b8161072a576040805162461bcd60e51b815260206004820152601760248201527f43616e6e6f742073657420415641582061646472657373000000000000000000604482015290519081900360640190fd5b60009182526006602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b6005546001600160a01b031681565b6001546001600160a01b031633146107b3576040805162461bcd60e51b815260206004820152600a60248201526961646d696e206f6e6c7960b01b604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6002600054141561082d576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556005546001600160a01b03166108795760405162461bcd60e51b81526004018080602001828103825260218152602001806114aa6021913960400191505060405180910390fd5b600554604080516370a0823160e01b815230600482015290516001600160a01b039092169160009183916370a0823191602480820192602092909190829003018186803b1580156108c957600080fd5b505afa1580156108dd573d6000803e3d6000fd5b505050506040513d60208110156108f357600080fd5b5051604080516323b872dd60e01b81523360048201523060248201526044810186905290519192506001600160a01b038416916323b872dd916064808201926020929091908290030181600087803b15801561094e57600080fd5b505af1158015610962573d6000803e3d6000fd5b505050506040513d602081101561097857600080fd5b5050604080516370a0823160e01b81523060048201529051600091610a029184916001600160a01b038716916370a0823191602480820192602092909190829003018186803b1580156109ca57600080fd5b505afa1580156109de573d6000803e3d6000fd5b505050506040513d60208110156109f457600080fd5b50519063ffffffff61115a16565b905060008111610a48576040805162461bcd60e51b815260206004820152600c60248201526b16995c9bc819195c1bdcda5d60a21b604482015290519081900360640190fd5b610a5133610e40565b600a54610a64908263ffffffff61124016565b600a5533600090815260096020526040902054610a87908263ffffffff61124016565b336000908152600960205260408120919091556001905550505050565b600d5481565b6001546001600160a01b03163314610af6576040805162461bcd60e51b815260206004820152600a60248201526961646d696e206f6e6c7960b01b604482015290519081900360640190fd5b600d5415610b0657610b0661129a565b60009182526007602052604090912055565b600a5481565b60026000541415610b76576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000556005546001600160a01b0316610bc25760405162461bcd60e51b81526004018080602001828103825260218152602001806114aa6021913960400191505060405180910390fd5b33600090815260096020526040902054811115610c1d576040805162461bcd60e51b8152602060048201526014602482015273151bdbc81b185c99d9481dda5d1a191c985dd85b60621b604482015290519081900360640190fd5b610c2633610e40565b33600090815260096020526040902054610c46908263ffffffff61115a16565b33600090815260096020526040902055600a54610c69908263ffffffff61115a16565b600a556005546040805163a9059cbb60e01b81523360048201526024810184905290516001600160a01b0390921691829163a9059cbb9160448083019260209291908290030181600087803b158015610cc157600080fd5b505af1158015610cd5573d6000803e3d6000fd5b505050506040513d6020811015610ceb57600080fd5b505060016000555050565b806001600160a01b031663f851a4406040518163ffffffff1660e01b815260040160206040518083038186803b158015610d2f57600080fd5b505afa158015610d43573d6000803e3d6000fd5b505050506040513d6020811015610d5957600080fd5b50516001600160a01b03163314610da15760405162461bcd60e51b815260040180806020018281038252602e81526020018061147c602e913960400191505060405180910390fd5b806001600160a01b03166316ec205c6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610ddc57600080fd5b505af1158015610df0573d6000803e3d6000fd5b5050505050565b600860209081526000928352604080842090915290825290205481565b600c60209081526000928352604080842090915290825290205481565b6001546001600160a01b031681565b610e4861129a565b60005b6002811015610f56576001600160a01b0382166000908152600c60209081526040808320848452825280832054600b909252822054610e8f9163ffffffff61115a16565b6001600160a01b03841660009081526009602052604081205491925090610ed2906ec097ce7bc90715b34b9f10000000009061064f90859063ffffffff6111a516565b6001600160a01b0385166000908152600860209081526040808320878452909152902054909150610f09908263ffffffff61124016565b6001600160a01b0385166000818152600860209081526040808320888452825280832094909455600b815283822054928252600c8152838220878352905291909120555050600101610e4b565b5050565b82610fac576040805162461bcd60e51b815260206004820152601e60248201527f43616e6e6f742075736520636c61696d457263323020666f7220415641580000604482015290519081900360640190fd5b6001600160a01b0382166000908152600860209081526040808320868452909152902054811015611024576040805162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f75676820616363727565642072657761726473000000000000604482015290519081900360640190fd5b6000838152600660205260409020546001600160a01b03166110775760405162461bcd60e51b81526004018080602001828103825260248152602001806114ec6024913960400191505060405180910390fd5b6000838152600660209081526040808320546001600160a01b038681168552600884528285208886529093529220549116906110b9908363ffffffff61115a16565b6001600160a01b0380851660008181526008602090815260408083208a8452825280832095909555845163a9059cbb60e01b815260048101939093526024830187905293519285169363a9059cbb93604480850194929391928390030190829087803b15801561112857600080fd5b505af115801561113c573d6000803e3d6000fd5b505050506040513d602081101561115257600080fd5b505050505050565b600061119c83836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f770081525061137f565b90505b92915050565b6000826111b45750600061119f565b828202828482816111c157fe5b041461119c5760405162461bcd60e51b81526004018080602001828103825260218152602001806114cb6021913960400191505060405180910390fd5b600061119c83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611416565b60008282018381101561119c576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006112b1600d544261115a90919063ffffffff16565b42600d5590508015806112c45750600a54155b156112cf575061137d565b60005b6002811015610f5657600081815260076020526040902054806112f55750611375565b600082815260076020526040812054611314908563ffffffff6111a516565b90506000611340600a5461064f6ec097ce7bc90715b34b9f1000000000856111a590919063ffffffff16565b6000858152600b6020526040902054909150611362908263ffffffff61124016565b6000858152600b60205260409020555050505b6001016112d2565b565b6000818484111561140e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156113d35781810151838201526020016113bb565b50505050905090810190601f1680156114005780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836114655760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156113d35781810151838201526020016113bb565b50600083858161147157fe5b049594505050505056fe4f6e6c792070726f78792061646d696e2063616e206368616e67652074686520696d706c656d656e746174696f6e50474c20546f6b656e20616464726573732063616e206e6f74206265207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7772657761726420746f6b656e20616464726573732063616e206e6f74206265207a65726fa265627a7a7231582031cd3321ccf85ce3dc07bcd01e60b36bb802b61bd290b9438c8020677d80285f64736f6c63430005110032

Deployed ByteCode Sourcemap

20819:8763:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13271:44;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13271:44:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;13271:44:0;-1:-1:-1;;;;;13271:44:0;;:::i;:::-;;;;;;;;;;;;;;;;13060:41;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13060:41:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;13060:41:0;;:::i;12309:27::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12309:27:0;;;:::i;:::-;;;;-1:-1:-1;;;;;12309:27:0;;;;;;;;;;;;;;22964:208;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22964:208:0;;;:::i;12485:36::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12485:36:0;;;:::i;12393:29::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12393:29:0;;;:::i;18278:40::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;18278:40:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;18278:40:0;;:::i;23396:591::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;23396:591:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23396:591:0;;:::i;12931:52::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12931:52:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12931:52:0;;:::i;24985:242::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24985:242:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24985:242:0;;;;;;-1:-1:-1;;;;;24985:242:0;;:::i;12847:30::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12847:30:0;;;:::i;25382:130::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25382:130:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25382:130:0;-1:-1:-1;;;;;25382:130:0;;:::i;21494:688::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21494:688:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21494:688:0;;:::i;18400:33::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;18400:33:0;;;:::i;24582:210::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24582:210:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24582:210:0;;;;;;;:::i;13363:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13363:25:0;;;:::i;22310:525::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22310:525:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;22310:525:0;;:::i;25655:221::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25655:221:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25655:221:0;-1:-1:-1;;;;;25655:221:0;;:::i;13163:62::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13163:62:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;13163:62:0;;;;;;;;:::i;18325:68::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;18325:68:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;18325:68:0;;;;;;;;:::i;12235:20::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12235:20:0;;;:::i;13271:44::-;;;;;;;;;;;;;:::o;13060:41::-;;;;;;;;;;;;;:::o;12309:27::-;;;-1:-1:-1;;;;;12309:27:0;;:::o;22964:208::-;1746:1;2349:7;;:19;;2341:63;;;;;-1:-1:-1;;;2341:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;1746:1;2482:7;:18;23021:28;23038:10;23021:16;:28::i;:::-;23090:10;23062:11;23076:25;;;:13;:25;;;;;;;;12794:1;23076:36;;;;;;;;;;23123:41;;12794:1;23076:36;23123:10;:41::i;:::-;-1:-1:-1;1702:1:0;2661:7;:22;22964:208::o;12485:36::-;;;-1:-1:-1;;;;;12485:36:0;;:::o;12393:29::-;;;-1:-1:-1;;;;;12393:29:0;;:::o;18278:40::-;;;;;;;;;;;;;:::o;23396:591::-;23465:4;12724:1;23490:11;:32;;23482:65;;;;;-1:-1:-1;;;23482:65:0;;;;;;;;;;;;-1:-1:-1;;;23482:65:0;;;;;;;;;;;;;;;23637:26;23633:67;;-1:-1:-1;23687:1:0;23680:8;;23633:67;23785:10;23712:21;23765:31;;;:19;:31;;;;;;;;:44;;;;;;;;;23736:11;:24;;;;;;:74;;;:28;:74;:::i;:::-;23919:10;23821:20;23905:25;;;:13;:25;;;;;;;;:38;;;;;;;;;23865:24;;;:12;:24;;;;;;23712:98;;-1:-1:-1;23821:20:0;23844:100;;23905:38;23844:56;;23895:4;;23844:46;;23712:98;;23844:46;:20;:46;:::i;:::-;:50;:56;:50;:56;:::i;:::-;:60;:100;:60;:100;:::i;:::-;23821:123;-1:-1:-1;;;23396:591:0;;;;:::o;12931:52::-;;;;;;;;;;;;-1:-1:-1;;;;;12931:52:0;;:::o;24985:242::-;29539:5;;-1:-1:-1;;;;;29539:5:0;29525:10;:19;29517:42;;;;;-1:-1:-1;;;29517:42:0;;;;;;;;;;;;-1:-1:-1;;;29517:42:0;;;;;;;;;;;;;;;25100:26;25092:62;;;;;-1:-1:-1;;;25092:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;25165:33;;;;:20;:33;;;;;;:54;;-1:-1:-1;;;;;;25165:54:0;-1:-1:-1;;;;;25165:54:0;;;;;;;;;24985:242::o;12847:30::-;;;-1:-1:-1;;;;;12847:30:0;;:::o;25382:130::-;29539:5;;-1:-1:-1;;;;;29539:5:0;29525:10;:19;29517:42;;;;;-1:-1:-1;;;29517:42:0;;;;;;;;;;;;-1:-1:-1;;;29517:42:0;;;;;;;;;;;;;;;25468:15;:36;;-1:-1:-1;;;;;;25468:36:0;-1:-1:-1;;;;;25468:36:0;;;;;;;;;;25382:130::o;21494:688::-;1746:1;2349:7;;:19;;2341:63;;;;;-1:-1:-1;;;2341:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;1746:1;2482:7;:18;21568:15;;-1:-1:-1;;;;;21568:15:0;21560:75;;;;-1:-1:-1;;;21560:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21689:15;;21739:33;;;-1:-1:-1;;;21739:33:0;;21766:4;21739:33;;;;;;-1:-1:-1;;;;;21689:15:0;;;;21648:23;;21689:15;;21739:18;;:33;;;;;;;;;;;;;;;21689:15;21739:33;;;5:2:-1;;;;30:1;27;20:12;5:2;21739:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21739:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21739:33:0;21783:59;;;-1:-1:-1;;;21783:59:0;;21805:10;21783:59;;;;21825:4;21783:59;;;;;;;;;;;;21739:33;;-1:-1:-1;;;;;;21783:21:0;;;;;:59;;;;;21739:33;;21783:59;;;;;;;;-1:-1:-1;21783:21:0;:59;;;5:2:-1;;;;30:1;27;20:12;5:2;21783:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21783:59:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;21876:33:0;;;-1:-1:-1;;;21876:33:0;;21903:4;21876:33;;;;;;21853:20;;21876:54;;21914:15;;-1:-1:-1;;;;;21876:18:0;;;;;:33;;;;;21783:59;;21876:33;;;;;;;;:18;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;21876:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21876:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21876:33:0;;:54;:37;:54;:::i;:::-;21853:77;;21969:1;21951:15;:19;21943:44;;;;;-1:-1:-1;;;21943:44:0;;;;;;;;;;;;-1:-1:-1;;;21943:44:0;;;;;;;;;;;;;;;22000:28;22017:10;22000:16;:28::i;:::-;22057:13;;:34;;22075:15;22057:34;:17;:34;:::i;:::-;22041:13;:50;22142:10;22129:24;;;;:12;:24;;;;;;:45;;22158:15;22129:45;:28;:45;:::i;:::-;22115:10;22102:24;;;;:12;:24;;;;;:72;;;;1702:1;2661:22;;-1:-1:-1;;;;21494:688:0:o;18400:33::-;;;;:::o;24582:210::-;29539:5;;-1:-1:-1;;;;;29539:5:0;29525:10;:19;29517:42;;;;;-1:-1:-1;;;29517:42:0;;;;;;;;;;;;-1:-1:-1;;;29517:42:0;;;;;;;;;;;;;;;24670:21;;:26;24666:73;;24713:14;:12;:14::i;:::-;24751:25;;;;:12;:25;;;;;;:33;24582:210::o;13363:25::-;;;;:::o;22310:525::-;1746:1;2349:7;;:19;;2341:63;;;;;-1:-1:-1;;;2341:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;1746:1;2482:7;:18;22383:15;;-1:-1:-1;;;;;22383:15:0;22375:75;;;;-1:-1:-1;;;22375:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22495:10;22482:24;;;;:12;:24;;;;;;22469:37;;;22461:70;;;;;-1:-1:-1;;;22461:70:0;;;;;;;;;;;;-1:-1:-1;;;22461:70:0;;;;;;;;;;;;;;;22544:28;22561:10;22544:16;:28::i;:::-;22625:10;22612:24;;;;:12;:24;;;;;;:39;;22641:9;22612:39;:28;:39;:::i;:::-;22598:10;22585:24;;;;:12;:24;;;;;:66;22678:13;;:28;;22696:9;22678:28;:17;:28;:::i;:::-;22662:13;:44;22760:15;;22787:40;;;-1:-1:-1;;;22787:40:0;;22805:10;22787:40;;;;;;;;;;;;-1:-1:-1;;;;;22760:15:0;;;;;;22787:17;;:40;;;;;;;;;;;;;;22719:23;22760:15;22787:40;;;5:2:-1;;;;30:1;27;20:12;5:2;22787:40:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;22787:40:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;1702:1:0;2661:7;:22;-1:-1:-1;;22310:525:0:o;25655:221::-;25758:5;-1:-1:-1;;;;;25758:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25758:13:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;25758:13:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;25758:13:0;-1:-1:-1;;;;;25744:27:0;:10;:27;25736:86;;;;-1:-1:-1;;;25736:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25833:5;-1:-1:-1;;;;;25833:33:0;;:35;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25833:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;25833:35:0;;;;25655:221;:::o;13163:62::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;18325:68::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;12235:20::-;;;-1:-1:-1;;;;;12235:20:0;;:::o;27246:498::-;27311:14;:12;:14::i;:::-;27343:6;27338:399;12724:1;27355;:21;27338:399;;;-1:-1:-1;;;;;27444:30:0;;27401:21;27444:30;;;:19;:30;;;;;;;;:33;;;;;;;;;27425:11;:14;;;;;;:53;;;:18;:53;:::i;:::-;-1:-1:-1;;;;;27535:23:0;;27493:18;27535:23;;;:12;:23;;;;;;27401:77;;-1:-1:-1;27493:18:0;27514:55;;27564:4;;27514:45;;27401:77;;27514:45;:20;:45;:::i;:55::-;-1:-1:-1;;;;;27614:24:0;;;;;;:13;:24;;;;;;;;:27;;;;;;;;;27493:76;;-1:-1:-1;27614:46:0;;27493:76;27614:46;:31;:46;:::i;:::-;-1:-1:-1;;;;;27584:24:0;;;;;;:13;:24;;;;;;;;:27;;;;;;;;:76;;;;27711:11;:14;;;;;;27675:30;;;:19;:30;;;;;:33;;;;;;;;;:50;-1:-1:-1;;27383:1:0;27378:6;27338:399;;;;27246:498;:::o;28559:600::-;28657:26;28649:69;;;;;-1:-1:-1;;;28649:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;28737:24:0;;;;;;:13;:24;;;;;;;;:37;;;;;;;;;:47;-1:-1:-1;28737:47:0;28729:86;;;;;-1:-1:-1;;;28729:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;28879:1;28834:33;;;:20;:33;;;;;;-1:-1:-1;;;;;28834:33:0;28826:96;;;;-1:-1:-1;;;28826:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28935:20;28973:33;;;:20;:33;;;;;;;;;-1:-1:-1;;;;;29058:24:0;;;;;:13;:24;;;;;:37;;;;;;;;;28973:33;;;29058:49;;29100:6;29058:49;:41;:49;:::i;:::-;-1:-1:-1;;;;;29018:24:0;;;;;;;:13;:24;;;;;;;;:37;;;;;;;;:89;;;;29118:33;;-1:-1:-1;;;29118:33:0;;;;;;;;;;;;;;;;;:14;;;;;;:33;;;;;29018:24;;29118:33;;;;;;;;;:14;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;29118:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;29118:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;28559:600:0:o;7340:137::-;7398:7;7425:44;7429:1;7432;7425:44;;;;;;;;;;;;;;;;;:3;:44::i;:::-;7418:51;;7340:137;;;;;:::o;8201:471::-;8259:7;8504:6;8500:47;;-1:-1:-1;8534:1:0;8527:8;;8500:47;8571:5;;;8575:1;8571;:5;:1;8595:5;;;;;:10;8587:56;;;;-1:-1:-1;;;8587:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9859:132;9917:7;9944:39;9948:1;9951;9944:39;;;;;;;;;;;;;;;;;:3;:39::i;6447:181::-;6505:7;6537:5;;;6561:6;;;;6553:46;;;;;-1:-1:-1;;;6553:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;26377:679;26421:24;26448:42;26468:21;;26448:15;:19;;:42;;;;:::i;:::-;26525:15;26501:21;:39;26421:69;-1:-1:-1;26557:24:0;;;:46;;-1:-1:-1;26585:13:0;;:18;26557:46;26553:85;;;26620:7;;;26553:85;26655:6;26650:399;12724:1;26667;:21;26650:399;;;26713:16;26732:15;;;:12;:15;;;;;;26766:16;26762:65;;26803:8;;;26762:65;26843:12;26858:15;;;:12;:15;;;;;;:40;;26878:19;26858:40;:19;:40;:::i;:::-;26843:55;;26913:18;26934:36;26956:13;;26934:17;26946:4;26934:7;:11;;:17;;;;:::i;:36::-;27004:14;;;;:11;:14;;;;;;26913:57;;-1:-1:-1;27004:33:0;;26913:57;27004:33;:18;:33;:::i;:::-;26987:14;;;;:11;:14;;;;;:50;-1:-1:-1;;;26650:399:0;26695:1;26690:6;26650:399;;26377:679;:::o;7766:192::-;7852:7;7888:12;7880:6;;;;7872:29;;;;-1:-1:-1;;;7872:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;7872:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;7924:5:0;;;7766:192::o;10479:345::-;10565:7;10667:12;10660:5;10652:28;;;;-1:-1:-1;;;10652:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;10652:28:0;;10691:9;10707:1;10703;:5;;;;;;;10479:345;-1:-1:-1;;;;;10479:345:0:o

Swarm Source

bzzr://31cd3321ccf85ce3dc07bcd01e60b36bb802b61bd290b9438c8020677d80285f
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.