ETH Price: $2,625.73 (-1.78%)

Contract

0x618B7b93b07Bf78D04B2e8FB2B1C3B48049F8ED5
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Enable Pool129206532021-07-29 12:13:191291 days ago1627560799IN
0x618B7b93...8049F8ED5
0 ETH0.0016474827
Enable Pool129206522021-07-29 12:13:101291 days ago1627560790IN
0x618B7b93...8049F8ED5
0 ETH0.0016474827
Enable Pool129206512021-07-29 12:13:071291 days ago1627560787IN
0x618B7b93...8049F8ED5
0 ETH0.0021088627
Disable Pool129195422021-07-29 8:06:271291 days ago1627545987IN
0x618B7b93...8049F8ED5
0 ETH0.0007305630
Disable Pool129195402021-07-29 8:06:001291 days ago1627545960IN
0x618B7b93...8049F8ED5
0 ETH0.000706229
Disable Pool129195392021-07-29 8:05:501291 days ago1627545950IN
0x618B7b93...8049F8ED5
0 ETH0.0007303830
Set Init Co Fi R...129195392021-07-29 8:05:501291 days ago1627545950IN
0x618B7b93...8049F8ED5
0 ETH0.0004284930
Batch Set Pool W...124498822021-05-17 4:52:221364 days ago1621227142IN
0x618B7b93...8049F8ED5
0 ETH0.0141288140
Add Pool124498802021-05-17 4:52:071364 days ago1621227127IN
0x618B7b93...8049F8ED5
0 ETH0.01478904140
Add Pool124498792021-05-17 4:52:031364 days ago1621227123IN
0x618B7b93...8049F8ED5
0 ETH0.01478904140
Add Pool124498702021-05-17 4:48:361364 days ago1621226916IN
0x618B7b93...8049F8ED5
0 ETH0.01957536140
Set Genesis Bloc...124494912021-05-17 3:23:501365 days ago1621221830IN
0x618B7b93...8049F8ED5
0 ETH0.0023652990

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CoFiXV2VaultForLP

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 6666 runs

Other Settings:
istanbul EvmVersion, GNU GPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-05-17
*/

// File: contracts/interface/ICoFiXV2VaultForTrader.sol

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

pragma solidity 0.6.12;

interface ICoFiXV2VaultForTrader {

    event RouterAllowed(address router);
    event RouterDisallowed(address router);

    event ClearPendingRewardOfCNode(uint256 pendingAmount);
    event ClearPendingRewardOfLP(uint256 pendingAmount);

    function setGovernance(address gov) external;

    function setCofiRate(uint256 cofiRate) external;

    function allowRouter(address router) external;

    function disallowRouter(address router) external;

    function calcMiningRate(address pair, uint256 neededETHAmount) external view returns (uint256);

    function calcNeededETHAmountForAdjustment(address pair, uint256 reserve0, uint256 reserve1, uint256 ethAmount, uint256 erc20Amount) external view returns (uint256);

    function actualMiningAmount(address pair, uint256 reserve0, uint256 reserve1, uint256 ethAmount, uint256 erc20Amount) external view returns (uint256 amount, uint256 totalAccruedAmount, uint256 neededETHAmount);

    function distributeReward(address pair, uint256 ethAmount, uint256 erc20Amount, address rewardTo) external;

    function clearPendingRewardOfCNode() external;

    function clearPendingRewardOfLP(address pair) external;

    function getPendingRewardOfCNode() external view returns (uint256);

    function getPendingRewardOfLP(address pair) external view returns (uint256);

}

// File: contracts/interface/ICoFiXV2Factory.sol

pragma solidity 0.6.12;

interface ICoFiXV2Factory {
    // All pairs: {ETH <-> ERC20 Token}
    event PairCreated(address indexed token, address pair, uint256);
    event NewGovernance(address _new);
    event NewController(address _new);
    event NewFeeReceiver(address _new);
    event NewFeeVaultForLP(address token, address feeVault);
    event NewVaultForLP(address _new);
    event NewVaultForTrader(address _new);
    event NewVaultForCNode(address _new);
    event NewDAO(address _new);

    /// @dev Create a new token pair for trading
    /// @param  token the address of token to trade
    /// @param  initToken0Amount the initial asset ratio (initToken0Amount:initToken1Amount)
    /// @param  initToken1Amount the initial asset ratio (initToken0Amount:initToken1Amount)
    /// @return pair the address of new token pair
    function createPair(
        address token,
	    uint256 initToken0Amount,
        uint256 initToken1Amount
        )
        external
        returns (address pair);

    function getPair(address token) external view returns (address pair);
    function allPairs(uint256) external view returns (address pair);
    function allPairsLength() external view returns (uint256);

    function getTradeMiningStatus(address token) external view returns (bool status);
    function setTradeMiningStatus(address token, bool status) external;
    function getFeeVaultForLP(address token) external view returns (address feeVault); // for LPs
    function setFeeVaultForLP(address token, address feeVault) external;

    function setGovernance(address _new) external;
    function setController(address _new) external;
    function setFeeReceiver(address _new) external;
    function setVaultForLP(address _new) external;
    function setVaultForTrader(address _new) external;
    function setVaultForCNode(address _new) external;
    function setDAO(address _new) external;
    function getController() external view returns (address controller);
    function getFeeReceiver() external view returns (address feeReceiver); // For CoFi Holders
    function getVaultForLP() external view returns (address vaultForLP);
    function getVaultForTrader() external view returns (address vaultForTrader);
    function getVaultForCNode() external view returns (address vaultForCNode);
    function getDAO() external view returns (address dao);
}

// File: @openzeppelin/contracts/utils/ReentrancyGuard.sol

pragma solidity >=0.6.0 <0.8.0;

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

// File: contracts/interface/ICoFiXStakingRewards.sol

pragma solidity 0.6.12;

interface ICoFiXStakingRewards {
    // Views

    /// @dev The rewards vault contract address set in factory contract
    /// @return Returns the vault address
    function rewardsVault() external view returns (address);

    /// @dev The lastBlock reward applicable
    /// @return Returns the latest block.number on-chain
    function lastBlockRewardApplicable() external view returns (uint256);

    /// @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 Get the latest reward rate of this mining pool (tokens amount per block)
    /// @return The latest reward rate
    function rewardRate() external view returns (uint256);

    /// @dev How many stakingToken (XToken) deposited into to this reward pool (mining pool)
    /// @return The total amount of XTokens deposited in this mining 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 mining pool
    function balanceOf(address account) external view returns (uint256);

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

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

    // Mutative

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

    /// @dev Stake/Deposit into the reward pool (mining 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 (mining 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;

    function getRewardAndStake() external;

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

    /// @dev Add reward to the mining pool
    function addReward(uint256 amount) external;

    // 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 EmergencyWithdraw(address indexed user, uint256 amount);
    event RewardPaid(address indexed user, uint256 reward);
}
// File: contracts/interface/ICoFiXVaultForLP.sol

pragma solidity 0.6.12;

interface ICoFiXVaultForLP {

    enum POOL_STATE {INVALID, ENABLED, DISABLED}

    event NewPoolAdded(address pool, uint256 index);
    event PoolEnabled(address pool);
    event PoolDisabled(address pool);

    function setGovernance(address _new) external;
    function setInitCoFiRate(uint256 _new) external;
    function setDecayPeriod(uint256 _new) external;
    function setDecayRate(uint256 _new) external;

    function addPool(address pool) external;
    function enablePool(address pool) external;
    function disablePool(address pool) external;
    function setPoolWeight(address pool, uint256 weight) external;
    function batchSetPoolWeight(address[] memory pools, uint256[] memory weights) external;
    function distributeReward(address to, uint256 amount) external;

    function getPendingRewardOfLP(address pair) external view returns (uint256);
    function currentPeriod() external view returns (uint256);
    function currentCoFiRate() external view returns (uint256);
    function currentPoolRate(address pool) external view returns (uint256 poolRate);
    function currentPoolRateByPair(address pair) external view returns (uint256 poolRate);

    /// @dev Get the award staking pool address of pair (XToken)
    /// @param  pair The address of XToken(pair) contract
    /// @return pool The pool address
    function stakingPoolForPair(address pair) external view returns (address pool);

    function getPoolInfo(address pool) external view returns (POOL_STATE state, uint256 weight);
    function getPoolInfoByPair(address pair) external view returns (POOL_STATE state, uint256 weight);

    function getEnabledPoolCnt() external view returns (uint256);

    function getCoFiStakingPool() external view returns (address pool);

}
// File: @openzeppelin/contracts/token/ERC20/IERC20.sol

pragma solidity >=0.6.0 <0.8.0;

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

// File: contracts/interface/ICoFiToken.sol

pragma solidity 0.6.12;

interface ICoFiToken is IERC20 {

    /// @dev An event thats emitted when a new governance account is set
    /// @param  _new The new governance address
    event NewGovernance(address _new);

    /// @dev An event thats emitted when a new minter account is added
    /// @param  _minter The new minter address added
    event MinterAdded(address _minter);

    /// @dev An event thats emitted when a minter account is removed
    /// @param  _minter The minter address removed
    event MinterRemoved(address _minter);

    /// @dev Set governance address of CoFi token. Only governance has the right to execute.
    /// @param  _new The new governance address
    function setGovernance(address _new) external;

    /// @dev Add a new minter account to CoFi token, who can mint tokens. Only governance has the right to execute.
    /// @param  _minter The new minter address
    function addMinter(address _minter) external;

    /// @dev Remove a minter account from CoFi token, who can mint tokens. Only governance has the right to execute.
    /// @param  _minter The minter address removed
    function removeMinter(address _minter) external;

    /// @dev mint is used to distribute CoFi token to users, minters are CoFi mining pools
    /// @param  _to The receiver address
    /// @param  _amount The amount of tokens minted
    function mint(address _to, uint256 _amount) external;
}

// File: contracts/lib/ABDKMath64x64.sol

/*
 * ABDK Math 64.64 Smart Contract Library.  Copyright © 2019 by ABDK Consulting.
 * Author: Mikhail Vladimirov <[email protected]>
 */
pragma solidity 0.6.12;

/**
 * Smart contract library of mathematical functions operating with signed
 * 64.64-bit fixed point numbers.  Signed 64.64-bit fixed point number is
 * basically a simple fraction whose numerator is signed 128-bit integer and
 * denominator is 2^64.  As long as denominator is always the same, there is no
 * need to store it, thus in Solidity signed 64.64-bit fixed point numbers are
 * represented by int128 type holding only the numerator.
 */
library ABDKMath64x64 {
  /**
   * @dev Minimum value signed 64.64-bit fixed point number may have. 
   */
  int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;

  /**
   * @dev Maximum value signed 64.64-bit fixed point number may have. 
   */
  int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

  /**
   * Convert signed 256-bit integer number into signed 64.64-bit fixed point
   * number.  Revert on overflow.
   *
   * @param x signed 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function fromInt (int256 x) internal pure returns (int128) {
    require (x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF);
    return int128 (x << 64);
  }

  /**
   * Convert signed 64.64 fixed point number into signed 64-bit integer number
   * rounding down.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64-bit integer number
   */
  function toInt (int128 x) internal pure returns (int64) {
    return int64 (x >> 64);
  }

  /**
   * Convert unsigned 256-bit integer number into signed 64.64-bit fixed point
   * number.  Revert on overflow.
   *
   * @param x unsigned 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function fromUInt (uint256 x) internal pure returns (int128) {
    require (x <= 0x7FFFFFFFFFFFFFFF);
    return int128 (x << 64);
  }

  /**
   * Convert signed 64.64 fixed point number into unsigned 64-bit integer
   * number rounding down.  Revert on underflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return unsigned 64-bit integer number
   */
  function toUInt (int128 x) internal pure returns (uint64) {
    require (x >= 0);
    return uint64 (x >> 64);
  }

  /**
   * Convert signed 128.128 fixed point number into signed 64.64-bit fixed point
   * number rounding down.  Revert on overflow.
   *
   * @param x signed 128.128-bin fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function from128x128 (int256 x) internal pure returns (int128) {
    int256 result = x >> 64;
    require (result >= MIN_64x64 && result <= MAX_64x64);
    return int128 (result);
  }

  /**
   * Convert signed 64.64 fixed point number into signed 128.128 fixed point
   * number.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 128.128 fixed point number
   */
  function to128x128 (int128 x) internal pure returns (int256) {
    return int256 (x) << 64;
  }

  /**
   * Calculate x + y.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function add (int128 x, int128 y) internal pure returns (int128) {
    int256 result = int256(x) + y;
    require (result >= MIN_64x64 && result <= MAX_64x64);
    return int128 (result);
  }

  /**
   * Calculate x - y.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function sub (int128 x, int128 y) internal pure returns (int128) {
    int256 result = int256(x) - y;
    require (result >= MIN_64x64 && result <= MAX_64x64);
    return int128 (result);
  }

  /**
   * Calculate x * y rounding down.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function mul (int128 x, int128 y) internal pure returns (int128) {
    int256 result = int256(x) * y >> 64;
    require (result >= MIN_64x64 && result <= MAX_64x64);
    return int128 (result);
  }

  /**
   * Calculate x * y rounding towards zero, where x is signed 64.64 fixed point
   * number and y is signed 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64 fixed point number
   * @param y signed 256-bit integer number
   * @return signed 256-bit integer number
   */
  function muli (int128 x, int256 y) internal pure returns (int256) {
    if (x == MIN_64x64) {
      require (y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF &&
        y <= 0x1000000000000000000000000000000000000000000000000);
      return -y << 63;
    } else {
      bool negativeResult = false;
      if (x < 0) {
        x = -x;
        negativeResult = true;
      }
      if (y < 0) {
        y = -y; // We rely on overflow behavior here
        negativeResult = !negativeResult;
      }
      uint256 absoluteResult = mulu (x, uint256 (y));
      if (negativeResult) {
        require (absoluteResult <=
          0x8000000000000000000000000000000000000000000000000000000000000000);
        return -int256 (absoluteResult); // We rely on overflow behavior here
      } else {
        require (absoluteResult <=
          0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
        return int256 (absoluteResult);
      }
    }
  }

  /**
   * Calculate x * y rounding down, where x is signed 64.64 fixed point number
   * and y is unsigned 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64 fixed point number
   * @param y unsigned 256-bit integer number
   * @return unsigned 256-bit integer number
   */
  function mulu (int128 x, uint256 y) internal pure returns (uint256) {
    if (y == 0) return 0;

    require (x >= 0);

    uint256 lo = (uint256 (x) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;
    uint256 hi = uint256 (x) * (y >> 128);

    require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
    hi <<= 64;

    require (hi <=
      0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo);
    return hi + lo;
  }

  /**
   * Calculate x / y rounding towards zero.  Revert on overflow or when y is
   * zero.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function div (int128 x, int128 y) internal pure returns (int128) {
    require (y != 0);
    int256 result = (int256 (x) << 64) / y;
    require (result >= MIN_64x64 && result <= MAX_64x64);
    return int128 (result);
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are signed 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x signed 256-bit integer number
   * @param y signed 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function divi (int256 x, int256 y) internal pure returns (int128) {
    require (y != 0);

    bool negativeResult = false;
    if (x < 0) {
      x = -x; // We rely on overflow behavior here
      negativeResult = true;
    }
    if (y < 0) {
      y = -y; // We rely on overflow behavior here
      negativeResult = !negativeResult;
    }
    uint128 absoluteResult = divuu (uint256 (x), uint256 (y));
    if (negativeResult) {
      require (absoluteResult <= 0x80000000000000000000000000000000);
      return -int128 (absoluteResult); // We rely on overflow behavior here
    } else {
      require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
      return int128 (absoluteResult); // We rely on overflow behavior here
    }
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x unsigned 256-bit integer number
   * @param y unsigned 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function divu (uint256 x, uint256 y) internal pure returns (int128) {
    require (y != 0);
    uint128 result = divuu (x, y);
    require (result <= uint128 (MAX_64x64));
    return int128 (result);
  }

  /**
   * Calculate -x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function neg (int128 x) internal pure returns (int128) {
    require (x != MIN_64x64);
    return -x;
  }

  /**
   * Calculate |x|.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function abs (int128 x) internal pure returns (int128) {
    require (x != MIN_64x64);
    return x < 0 ? -x : x;
  }

  /**
   * Calculate 1 / x rounding towards zero.  Revert on overflow or when x is
   * zero.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function inv (int128 x) internal pure returns (int128) {
    require (x != 0);
    int256 result = int256 (0x100000000000000000000000000000000) / x;
    require (result >= MIN_64x64 && result <= MAX_64x64);
    return int128 (result);
  }

  /**
   * Calculate arithmetics average of x and y, i.e. (x + y) / 2 rounding down.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function avg (int128 x, int128 y) internal pure returns (int128) {
    return int128 ((int256 (x) + int256 (y)) >> 1);
  }

  /**
   * Calculate geometric average of x and y, i.e. sqrt (x * y) rounding down.
   * Revert on overflow or in case x * y is negative.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function gavg (int128 x, int128 y) internal pure returns (int128) {
    int256 m = int256 (x) * int256 (y);
    require (m >= 0);
    require (m <
        0x4000000000000000000000000000000000000000000000000000000000000000);
    return int128 (sqrtu (uint256 (m), uint256 (x) + uint256 (y) >> 1));
  }

  /**
   * Calculate x^y assuming 0^0 is 1, where x is signed 64.64 fixed point number
   * and y is unsigned 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y uint256 value
   * @return signed 64.64-bit fixed point number
   */
  function pow (int128 x, uint256 y) internal pure returns (int128) {
    uint256 absoluteResult;
    bool negativeResult = false;
    if (x >= 0) {
      absoluteResult = powu (uint256 (x) << 63, y);
    } else {
      // We rely on overflow behavior here
      absoluteResult = powu (uint256 (uint128 (-x)) << 63, y);
      negativeResult = y & 1 > 0;
    }

    absoluteResult >>= 63;

    if (negativeResult) {
      require (absoluteResult <= 0x80000000000000000000000000000000);
      return -int128 (absoluteResult); // We rely on overflow behavior here
    } else {
      require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
      return int128 (absoluteResult); // We rely on overflow behavior here
    }
  }

  /**
   * Calculate sqrt (x) rounding down.  Revert if x < 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function sqrt (int128 x) internal pure returns (int128) {
    require (x >= 0);
    return int128 (sqrtu (uint256 (x) << 64, 0x10000000000000000));
  }

  /**
   * Calculate binary logarithm of x.  Revert if x <= 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function log_2 (int128 x) internal pure returns (int128) {
    require (x > 0);

    int256 msb = 0;
    int256 xc = x;
    if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; }
    if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
    if (xc >= 0x10000) { xc >>= 16; msb += 16; }
    if (xc >= 0x100) { xc >>= 8; msb += 8; }
    if (xc >= 0x10) { xc >>= 4; msb += 4; }
    if (xc >= 0x4) { xc >>= 2; msb += 2; }
    if (xc >= 0x2) msb += 1;  // No need to shift xc anymore

    int256 result = msb - 64 << 64;
    uint256 ux = uint256 (x) << 127 - msb;
    for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) {
      ux *= ux;
      uint256 b = ux >> 255;
      ux >>= 127 + b;
      result += bit * int256 (b);
    }

    return int128 (result);
  }

  /**
   * Calculate natural logarithm of x.  Revert if x <= 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function ln (int128 x) internal pure returns (int128) {
    require (x > 0);

    return int128 (
        uint256 (log_2 (x)) * 0xB17217F7D1CF79ABC9E3B39803F2F6AF >> 128);
  }

  /**
   * Calculate binary exponent of x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function exp_2 (int128 x) internal pure returns (int128) {
    require (x < 0x400000000000000000); // Overflow

    if (x < -0x400000000000000000) return 0; // Underflow

    uint256 result = 0x80000000000000000000000000000000;

    if (x & 0x8000000000000000 > 0)
      result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128;
    if (x & 0x4000000000000000 > 0)
      result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128;
    if (x & 0x2000000000000000 > 0)
      result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128;
    if (x & 0x1000000000000000 > 0)
      result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128;
    if (x & 0x800000000000000 > 0)
      result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128;
    if (x & 0x400000000000000 > 0)
      result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128;
    if (x & 0x200000000000000 > 0)
      result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128;
    if (x & 0x100000000000000 > 0)
      result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128;
    if (x & 0x80000000000000 > 0)
      result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128;
    if (x & 0x40000000000000 > 0)
      result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128;
    if (x & 0x20000000000000 > 0)
      result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128;
    if (x & 0x10000000000000 > 0)
      result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128;
    if (x & 0x8000000000000 > 0)
      result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128;
    if (x & 0x4000000000000 > 0)
      result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128;
    if (x & 0x2000000000000 > 0)
      result = result * 0x1000162E525EE054754457D5995292026 >> 128;
    if (x & 0x1000000000000 > 0)
      result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128;
    if (x & 0x800000000000 > 0)
      result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128;
    if (x & 0x400000000000 > 0)
      result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128;
    if (x & 0x200000000000 > 0)
      result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128;
    if (x & 0x100000000000 > 0)
      result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128;
    if (x & 0x80000000000 > 0)
      result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128;
    if (x & 0x40000000000 > 0)
      result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128;
    if (x & 0x20000000000 > 0)
      result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128;
    if (x & 0x10000000000 > 0)
      result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128;
    if (x & 0x8000000000 > 0)
      result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128;
    if (x & 0x4000000000 > 0)
      result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128;
    if (x & 0x2000000000 > 0)
      result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128;
    if (x & 0x1000000000 > 0)
      result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128;
    if (x & 0x800000000 > 0)
      result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128;
    if (x & 0x400000000 > 0)
      result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128;
    if (x & 0x200000000 > 0)
      result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128;
    if (x & 0x100000000 > 0)
      result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128;
    if (x & 0x80000000 > 0)
      result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128;
    if (x & 0x40000000 > 0)
      result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128;
    if (x & 0x20000000 > 0)
      result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128;
    if (x & 0x10000000 > 0)
      result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128;
    if (x & 0x8000000 > 0)
      result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128;
    if (x & 0x4000000 > 0)
      result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128;
    if (x & 0x2000000 > 0)
      result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128;
    if (x & 0x1000000 > 0)
      result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128;
    if (x & 0x800000 > 0)
      result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128;
    if (x & 0x400000 > 0)
      result = result * 0x100000000002C5C85FDF477B662B26945 >> 128;
    if (x & 0x200000 > 0)
      result = result * 0x10000000000162E42FEFA3AE53369388C >> 128;
    if (x & 0x100000 > 0)
      result = result * 0x100000000000B17217F7D1D351A389D40 >> 128;
    if (x & 0x80000 > 0)
      result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128;
    if (x & 0x40000 > 0)
      result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128;
    if (x & 0x20000 > 0)
      result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128;
    if (x & 0x10000 > 0)
      result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128;
    if (x & 0x8000 > 0)
      result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128;
    if (x & 0x4000 > 0)
      result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128;
    if (x & 0x2000 > 0)
      result = result * 0x1000000000000162E42FEFA39F02B772C >> 128;
    if (x & 0x1000 > 0)
      result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128;
    if (x & 0x800 > 0)
      result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128;
    if (x & 0x400 > 0)
      result = result * 0x100000000000002C5C85FDF473DEA871F >> 128;
    if (x & 0x200 > 0)
      result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128;
    if (x & 0x100 > 0)
      result = result * 0x100000000000000B17217F7D1CF79E949 >> 128;
    if (x & 0x80 > 0)
      result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128;
    if (x & 0x40 > 0)
      result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128;
    if (x & 0x20 > 0)
      result = result * 0x100000000000000162E42FEFA39EF366F >> 128;
    if (x & 0x10 > 0)
      result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128;
    if (x & 0x8 > 0)
      result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128;
    if (x & 0x4 > 0)
      result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128;
    if (x & 0x2 > 0)
      result = result * 0x1000000000000000162E42FEFA39EF358 >> 128;
    if (x & 0x1 > 0)
      result = result * 0x10000000000000000B17217F7D1CF79AB >> 128;

    result >>= 63 - (x >> 64);
    require (result <= uint256 (MAX_64x64));

    return int128 (result);
  }

  /**
   * Calculate natural exponent of x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function exp (int128 x) internal pure returns (int128) {
    require (x < 0x400000000000000000); // Overflow

    if (x < -0x400000000000000000) return 0; // Underflow

    return exp_2 (
        int128 (int256 (x) * 0x171547652B82FE1777D0FFDA0D23A7D12 >> 128));
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x unsigned 256-bit integer number
   * @param y unsigned 256-bit integer number
   * @return unsigned 64.64-bit fixed point number
   */
  function divuu (uint256 x, uint256 y) private pure returns (uint128) {
    require (y != 0);

    uint256 result;

    if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
      result = (x << 64) / y;
    else {
      uint256 msb = 192;
      uint256 xc = x >> 192;
      if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
      if (xc >= 0x10000) { xc >>= 16; msb += 16; }
      if (xc >= 0x100) { xc >>= 8; msb += 8; }
      if (xc >= 0x10) { xc >>= 4; msb += 4; }
      if (xc >= 0x4) { xc >>= 2; msb += 2; }
      if (xc >= 0x2) msb += 1;  // No need to shift xc anymore

      result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1);
      require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);

      uint256 hi = result * (y >> 128);
      uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);

      uint256 xh = x >> 192;
      uint256 xl = x << 64;

      if (xl < lo) xh -= 1;
      xl -= lo; // We rely on overflow behavior here
      lo = hi << 128;
      if (xl < lo) xh -= 1;
      xl -= lo; // We rely on overflow behavior here

      assert (xh == hi >> 128);

      result += xl / y;
    }

    require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
    return uint128 (result);
  }

  /**
   * Calculate x^y assuming 0^0 is 1, where x is unsigned 129.127 fixed point
   * number and y is unsigned 256-bit integer number.  Revert on overflow.
   *
   * @param x unsigned 129.127-bit fixed point number
   * @param y uint256 value
   * @return unsigned 129.127-bit fixed point number
   */
  function powu (uint256 x, uint256 y) private pure returns (uint256) {
    if (y == 0) return 0x80000000000000000000000000000000;
    else if (x == 0) return 0;
    else {
      int256 msb = 0;
      uint256 xc = x;
      if (xc >= 0x100000000000000000000000000000000) { xc >>= 128; msb += 128; }
      if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; }
      if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
      if (xc >= 0x10000) { xc >>= 16; msb += 16; }
      if (xc >= 0x100) { xc >>= 8; msb += 8; }
      if (xc >= 0x10) { xc >>= 4; msb += 4; }
      if (xc >= 0x4) { xc >>= 2; msb += 2; }
      if (xc >= 0x2) msb += 1;  // No need to shift xc anymore

      int256 xe = msb - 127;
      if (xe > 0) x >>= xe;
      else x <<= -xe;

      uint256 result = 0x80000000000000000000000000000000;
      int256 re = 0;

      while (y > 0) {
        if (y & 1 > 0) {
          result = result * x;
          y -= 1;
          re += xe;
          if (result >=
            0x8000000000000000000000000000000000000000000000000000000000000000) {
            result >>= 128;
            re += 1;
          } else result >>= 127;
          if (re < -127) return 0; // Underflow
          require (re < 128); // Overflow
        } else {
          x = x * x;
          y >>= 1;
          xe <<= 1;
          if (x >=
            0x8000000000000000000000000000000000000000000000000000000000000000) {
            x >>= 128;
            xe += 1;
          } else x >>= 127;
          if (xe < -127) return 0; // Underflow
          require (xe < 128); // Overflow
        }
      }

      if (re > 0) result <<= re;
      else if (re < 0) result >>= -re;

      return result;
    }
  }

  /**
   * Calculate sqrt (x) rounding down, where x is unsigned 256-bit integer
   * number.
   *
   * @param x unsigned 256-bit integer number
   * @return unsigned 128-bit integer number
   */
  function sqrtu (uint256 x, uint256 r) private pure returns (uint128) {
    if (x == 0) return 0;
    else {
      require (r > 0);
      while (true) {
        uint256 rr = x / r;
        if (r == rr || r + 1 == rr) return uint128 (r);
        else if (r == rr + 1) return uint128 (rr);
        r = r + rr + 1 >> 1;
      }
    }
  }
}

// File: @openzeppelin/contracts/math/SafeMath.sol

pragma solidity >=0.6.0 <0.8.0;

/**
 * @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, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, 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 (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

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

    /**
     * @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) {
        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, reverting 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) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * 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);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * 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);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * 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: contracts/CoFiXV2VaultForLP.sol

pragma solidity 0.6.12;

// Reward Pool Controller for Liquidity Provider
contract CoFiXV2VaultForLP is ICoFiXVaultForLP, ReentrancyGuard {

    using SafeMath for uint256;

    // uint256 public constant RATE_BASE = 1e18;
    uint256 public constant WEIGHT_BASE = 100;

    address public immutable cofiToken;
    address public immutable factory;

    uint256 public genesisBlock;

    // managed by governance
    address public governance;

    uint256 public initCoFiRate = 1.8*1e18; // yield per block  5*1e18 - 5*1e18/10
    uint256 public decayPeriod = 2400000; // yield decays for every 2,400,000 blocks
    uint256 public decayRate = 80;

    address[] public allPools; // add every pool addr to record, make it easier to track

    uint256 public enabledCnt;

    struct PoolInfo {
        POOL_STATE state;
        uint256 weight;
    }

    mapping (address => PoolInfo) public poolInfo; // pool -> poolInfo

    mapping (address => address) public pairToStakingPool; // pair -> staking pool

    modifier onlyGovernance() {
        require(msg.sender == governance, "CVaultForLP: !governance");
        _;
    }

    constructor(address cofi, address _factory) public {
        cofiToken = cofi;
        factory = _factory;
        governance = msg.sender;
        genesisBlock = block.number; // set v1 genesisBlock to genesisBlock later
    }

    // this is for mainnet
    function setGenesisBlock() external {
        genesisBlock = 11040688; // follow v1 
    }

    /* setters for protocol governance */
    function setGovernance(address _new) external override onlyGovernance {
        governance = _new;
    }

    function setInitCoFiRate(uint256 _new) external override onlyGovernance {
        initCoFiRate = _new;
    }

    function setDecayPeriod(uint256 _new) external override onlyGovernance {
        require(_new != 0, "CVaultForLP: wrong period setting");
        decayPeriod = _new;
    }

    function setDecayRate(uint256 _new) external override onlyGovernance {
        decayRate = _new;
    }

    function addPool(address pool) external override onlyGovernance {
        require(poolInfo[pool].state == POOL_STATE.INVALID, "CVaultForLP: pool added"); // INVALID -> ENABLED
        require(pool != address(0), "CVaultForTrader: invalid pool");
        poolInfo[pool].state = POOL_STATE.ENABLED;
        // default rate is zero, to ensure safety
        enabledCnt = enabledCnt.add(1);
        // set pair to reward pool map
        address pair = ICoFiXStakingRewards(pool).stakingToken();
        require(pairToStakingPool[pair] == address(0), "CVaultForLP: pair added");
        pairToStakingPool[pair] = pool; // staking token is CoFiXPair (XToken)
        allPools.push(pool); // add once never delete, using for track
        emit NewPoolAdded(pool, allPools.length);
    }

    function enablePool(address pool) external override onlyGovernance {
        require(poolInfo[pool].state == POOL_STATE.DISABLED, "CVaultForLP: pool not disabled"); // DISABLED -> ENABLED
        require(pool != address(0), "CVaultForTrader: invalid pool");
        poolInfo[pool].state = POOL_STATE.ENABLED;
        enabledCnt = enabledCnt.add(1);
        // set pair to reward pool map
        address pair = ICoFiXStakingRewards(pool).stakingToken();
        require(pairToStakingPool[pair] == address(0), "CVaultForLP: pair added");
        pairToStakingPool[pair] = pool; // staking token is CoFiXPair (XToken)
        emit PoolEnabled(pool);
    }

    function disablePool(address pool) external override onlyGovernance {
        require(poolInfo[pool].state == POOL_STATE.ENABLED, "CVaultForLP: pool not enabled"); // ENABLED -> DISABLED
        require(pool != address(0), "CVaultForTrader: invalid pool");
        poolInfo[pool].state = POOL_STATE.DISABLED;
        poolInfo[pool].weight = 0; // set pool weight to zero;
        enabledCnt = enabledCnt.sub(1);
        address pair = ICoFiXStakingRewards(pool).stakingToken();
        pairToStakingPool[pair] = address(0); // set pair mapping to zero
        emit PoolDisabled(pool);
    }

    function setPoolWeight(address pool, uint256 weight) public override onlyGovernance {
        require(weight <= WEIGHT_BASE, "CVaultForLP: invalid weight");
        require(pool != address(0), "CVaultForTrader: invalid pool");
        require(poolInfo[pool].state == POOL_STATE.ENABLED, "CVaultForLP: pool not enabled"); // only set weight if pool is enabled
        poolInfo[pool].weight = weight;
    }

    function batchSetPoolWeight(address[] memory pools, uint256[] memory weights) external override onlyGovernance {
        uint256 cnt = pools.length;
        require(cnt == weights.length, "CVaultForLP: mismatch len");
        for (uint256 i = 0; i < cnt; i++) {
            require(pools[i] != address(0), "CVaultForTrader: invalid pool");
            require(weights[i] <= WEIGHT_BASE, "CVaultForLP: invalid weight");
            require(poolInfo[pools[i]].state == POOL_STATE.ENABLED, "CVaultForLP: pool not enabled"); // only set weight if pool is enabled
            poolInfo[pools[i]].weight = weights[i];
        }
        // governance should ensure total weights equal to WEIGHT_BASE
    }
    
    function getPendingRewardOfLP(address pair) external override view returns (uint256) {
        POOL_STATE poolState = poolInfo[msg.sender].state;
        if (poolState == POOL_STATE.INVALID || poolState == POOL_STATE.DISABLED) {
            return 0; // if pool is disabled, it can't mint by call distributeReward, so don't count on any reward for it
        }
        // if poolState is enabled, then go on
        address vaultForTrader = ICoFiXV2Factory(factory).getVaultForTrader();
        if (vaultForTrader == address(0)) {
            return 0; // vaultForTrader is not set yet
        }
        uint256 pending = ICoFiXV2VaultForTrader(vaultForTrader).getPendingRewardOfLP(pair);
        return pending;
    }

    function distributeReward(address to, uint256 amount) external override nonReentrant {
        POOL_STATE poolState = poolInfo[msg.sender].state;
        require(poolState != POOL_STATE.INVALID, "CVaultForLP: only pool valid");
        if (poolState == POOL_STATE.DISABLED) {
            return; // make sure tx would revert because user still want to withdraw and getReward
        }
        require(to != address(0), "CVaultForTrader: invalid to");
        // if poolState is enabled, then go on. caution: be careful when adding new pool
        address vaultForTrader = ICoFiXV2Factory(factory).getVaultForTrader();
        if (vaultForTrader != address(0)) { // if equal, means vaultForTrader is not set yet
            address pair = ICoFiXStakingRewards(msg.sender).stakingToken();
            require(pair != address(0), "CVaultForTrader: invalid pair");
            uint256 pending = ICoFiXV2VaultForTrader(vaultForTrader).getPendingRewardOfLP(pair);
            if (pending > 0) {
                ICoFiXV2VaultForTrader(vaultForTrader).clearPendingRewardOfLP(pair);
            }
        }
        ICoFiToken(cofiToken).mint(to, amount); // allows zero
    }

    function currentPeriod() public override view returns (uint256) {
        return (block.number).sub(genesisBlock).div(decayPeriod);
    }

    function currentCoFiRate() public override view returns (uint256) {
        uint256 periodIdx = currentPeriod();
        if (periodIdx > 4) {
            periodIdx = 4; // after 5 years, the rate keep constant
        }
        uint256 cofiRate = initCoFiRate;
        uint256 _decayRate = decayRate;
        for (uint256 i = 0; i < periodIdx; i++) {
            cofiRate = cofiRate.mul(_decayRate).div(100);
        }
        return cofiRate;
    }

    function currentPoolRate(address pool) public override view returns (uint256 poolRate) {
        uint256 cnt = enabledCnt;
        if (cnt == 0) {
            return 0;
        }
        uint256 cofiRate = currentCoFiRate();
        uint256 weight = poolInfo[pool].weight;
        poolRate = cofiRate.mul(weight).div(WEIGHT_BASE);
        return poolRate;
    }

    function currentPoolRateByPair(address pair) external override view returns (uint256 poolRate) {
        address pool = pairToStakingPool[pair];
        poolRate = currentPoolRate(pool);
        return poolRate;
    }

    function stakingPoolForPair(address pair) external override view returns (address pool) {
        return pairToStakingPool[pair];
    }

    function getPoolInfo(address pool) public override view returns (POOL_STATE state, uint256 weight) {
        state = poolInfo[pool].state;
        weight = poolInfo[pool].weight;
        return (state, weight);
    }

    function getPoolInfoByPair(address pair) external override view returns (POOL_STATE state, uint256 weight) {
        address pool = pairToStakingPool[pair];
        return getPoolInfo(pool);
    }

    // pools in enabled state
    function getEnabledPoolCnt() external override view returns (uint256) {
        return enabledCnt;
    }

    function getCoFiStakingPool() external override view returns (address pool) {
        return ICoFiXV2Factory(factory).getFeeReceiver();
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"cofi","type":"address"},{"internalType":"address","name":"_factory","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"NewPoolAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pool","type":"address"}],"name":"PoolDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pool","type":"address"}],"name":"PoolEnabled","type":"event"},{"inputs":[],"name":"WEIGHT_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"name":"addPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allPools","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"pools","type":"address[]"},{"internalType":"uint256[]","name":"weights","type":"uint256[]"}],"name":"batchSetPoolWeight","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cofiToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentCoFiRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"name":"currentPoolRate","outputs":[{"internalType":"uint256","name":"poolRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"currentPoolRateByPair","outputs":[{"internalType":"uint256","name":"poolRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decayPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decayRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"name":"disablePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"distributeReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"name":"enablePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enabledCnt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCoFiStakingPool","outputs":[{"internalType":"address","name":"pool","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEnabledPoolCnt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"getPendingRewardOfLP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"name":"getPoolInfo","outputs":[{"internalType":"enum ICoFiXVaultForLP.POOL_STATE","name":"state","type":"uint8"},{"internalType":"uint256","name":"weight","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"getPoolInfoByPair","outputs":[{"internalType":"enum ICoFiXVaultForLP.POOL_STATE","name":"state","type":"uint8"},{"internalType":"uint256","name":"weight","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initCoFiRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pairToStakingPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolInfo","outputs":[{"internalType":"enum ICoFiXVaultForLP.POOL_STATE","name":"state","type":"uint8"},{"internalType":"uint256","name":"weight","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_new","type":"uint256"}],"name":"setDecayPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_new","type":"uint256"}],"name":"setDecayRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setGenesisBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_new","type":"address"}],"name":"setGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_new","type":"uint256"}],"name":"setInitCoFiRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"weight","type":"uint256"}],"name":"setPoolWeight","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"stakingPoolForPair","outputs":[{"internalType":"address","name":"pool","type":"address"}],"stateMutability":"view","type":"function"}]

60c06040526718fae27693b4000060035562249f00600455605060055534801561002857600080fd5b5060405161208d38038061208d8339818101604052604081101561004b57600080fd5b508051602090910151600160008190556001600160601b0319606093841b81166080529190921b1660a052600280546001600160a01b0319163317905543905560805160601c60a05160601c611fc56100c860003980610a3e52806114e252806116a75280611795525080610c8652806113b45250611fc56000f3fe608060405234801561001057600080fd5b506004361061020b5760003560e01c80635d941dd51161012a578063b26acd7a116100bd578063d914cd4b1161008c578063defe80ef11610071578063defe80ef1461065d578063e665cfe014610665578063f8a6d78f1461068b5761020b565b8063d914cd4b14610611578063dcaaa61b146106375761020b565b8063b26acd7a146105a0578063c45a0155146105bd578063cc28ac6a146105c5578063cc442f7c146105eb5761020b565b8063a66771db116100f9578063a66771db14610544578063a9c1f2f11461056a578063ab033ea914610572578063af1734ac146105985761020b565b80635d941dd5146104e8578063643a8b24146104f057806379d5d863146105165780639a7b5f111461051e5761020b565b806338d8294b116101a25780634cdc9c63116101715780634cdc9c63146104aa57806355d9cdff146104b2578063595aeb50146104ba5780635aa6e675146104e05761020b565b806338d8294b1461031c5780633be8b7681461035e57806341d1de971461048557806348d67e1b146104a25761020b565b80630c5890a0116101de5780630c5890a0146102c35780631ec8bb8c146102cb57806324de74bd146102f7578063342f802b146102ff5761020b565b806304e7e0b914610210578063060406181461022f57806306bfa9381461024957806307ec6c8114610297575b600080fd5b61022d6004803603602081101561022657600080fd5b5035610693565b005b6102376106f7565b60408051918252519081900360200190f35b61026f6004803603602081101561025f57600080fd5b50356001600160a01b031661071f565b6040518083600281111561027f57fe5b81526020018281526020019250505060405180910390f35b61022d600480360360408110156102ad57600080fd5b506001600160a01b038135169060200135610746565b6102376108f0565b61022d600480360360408110156102e157600080fd5b506001600160a01b0381351690602001356108f6565b610237610d1f565b61022d6004803603602081101561031557600080fd5b5035610d25565b6103426004803603602081101561033257600080fd5b50356001600160a01b0316610dc5565b604080516001600160a01b039092168252519081900360200190f35b61022d6004803603604081101561037457600080fd5b81019060208101813564010000000081111561038f57600080fd5b8201836020820111156103a157600080fd5b803590602001918460208302840111640100000000831117156103c357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561041357600080fd5b82018360208201111561042557600080fd5b8035906020019184602083028401116401000000008311171561044757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610de6945050505050565b6103426004803603602081101561049b57600080fd5b5035611087565b6102376110ae565b6102376110b4565b61022d6110ba565b61022d600480360360208110156104d057600080fd5b50356001600160a01b03166110c3565b6103426113a3565b6103426113b2565b6102376004803603602081101561050657600080fd5b50356001600160a01b03166113d6565b61023761142c565b61026f6004803603602081101561053457600080fd5b50356001600160a01b0316611479565b6102376004803603602081101561055a57600080fd5b50356001600160a01b0316611498565b610237611604565b61022d6004803603602081101561058857600080fd5b50356001600160a01b031661160a565b6103426116a3565b61022d600480360360208110156105b657600080fd5b503561172f565b610342611793565b610342600480360360208110156105db57600080fd5b50356001600160a01b03166117b7565b61026f6004803603602081101561060157600080fd5b50356001600160a01b03166117d2565b61022d6004803603602081101561062757600080fd5b50356001600160a01b0316611804565b61022d6004803603602081101561064d57600080fd5b50356001600160a01b0316611b25565b610237611d99565b6102376004803603602081101561067b57600080fd5b50356001600160a01b0316611d9e565b610237611dcb565b6002546001600160a01b031633146106f2576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b600555565b600061071a60045461071460015443611dd190919063ffffffff16565b90611e33565b905090565b6001600160a01b03166000908152600860205260409020805460019091015460ff90911691565b6002546001600160a01b031633146107a5576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b60648111156107fb576040805162461bcd60e51b815260206004820152601b60248201527f435661756c74466f724c503a20696e76616c6964207765696768740000000000604482015290519081900360640190fd5b6001600160a01b038216610856576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f725472616465723a20696e76616c696420706f6f6c000000604482015290519081900360640190fd5b60016001600160a01b03831660009081526008602052604090205460ff16600281111561087f57fe5b146108d1576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f724c503a20706f6f6c206e6f7420656e61626c6564000000604482015290519081900360640190fd5b6001600160a01b03909116600090815260086020526040902060010155565b60035481565b6002600054141561094e576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260009081553381526008602052604081205460ff169081600281111561097257fe5b14156109c5576040805162461bcd60e51b815260206004820152601c60248201527f435661756c74466f724c503a206f6e6c7920706f6f6c2076616c696400000000604482015290519081900360640190fd5b60028160028111156109d357fe5b14156109df5750610d16565b6001600160a01b038316610a3a576040805162461bcd60e51b815260206004820152601b60248201527f435661756c74466f725472616465723a20696e76616c696420746f0000000000604482015290519081900360640190fd5b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b58aa4786040518163ffffffff1660e01b815260040160206040518083038186803b158015610a9557600080fd5b505afa158015610aa9573d6000803e3d6000fd5b505050506040513d6020811015610abf57600080fd5b505190506001600160a01b03811615610c84576000336001600160a01b03166372f702f36040518163ffffffff1660e01b815260040160206040518083038186803b158015610b0d57600080fd5b505afa158015610b21573d6000803e3d6000fd5b505050506040513d6020811015610b3757600080fd5b505190506001600160a01b038116610b96576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f725472616465723a20696e76616c69642070616972000000604482015290519081900360640190fd5b6000826001600160a01b031663a66771db836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610be557600080fd5b505afa158015610bf9573d6000803e3d6000fd5b505050506040513d6020811015610c0f57600080fd5b505190508015610c8157826001600160a01b0316633d1b7dcc836040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b158015610c6857600080fd5b505af1158015610c7c573d6000803e3d6000fd5b505050505b50505b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166340c10f1985856040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015610cfb57600080fd5b505af1158015610d0f573d6000803e3d6000fd5b5050505050505b50506001600055565b60075490565b6002546001600160a01b03163314610d84576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b80610dc05760405162461bcd60e51b8152600401808060200182810382526021815260200180611f6f6021913960400191505060405180910390fd5b600455565b6001600160a01b03808216600090815260096020526040902054165b919050565b6002546001600160a01b03163314610e45576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b815181518114610e9c576040805162461bcd60e51b815260206004820152601960248201527f435661756c74466f724c503a206d69736d61746368206c656e00000000000000604482015290519081900360640190fd5b60005b818110156110815760006001600160a01b0316848281518110610ebe57fe5b60200260200101516001600160a01b03161415610f22576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f725472616465723a20696e76616c696420706f6f6c000000604482015290519081900360640190fd5b6064838281518110610f3057fe5b60200260200101511115610f8b576040805162461bcd60e51b815260206004820152601b60248201527f435661756c74466f724c503a20696e76616c6964207765696768740000000000604482015290519081900360640190fd5b600160086000868481518110610f9d57fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff166002811115610fcf57fe5b14611021576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f724c503a20706f6f6c206e6f7420656e61626c6564000000604482015290519081900360640190fd5b82818151811061102d57fe5b60200260200101516008600086848151811061104557fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600101819055508080600101915050610e9f565b50505050565b6006818154811061109457fe5b6000918252602090912001546001600160a01b0316905081565b60045481565b60015481565b62a877b0600155565b6002546001600160a01b03163314611122576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b60026001600160a01b03821660009081526008602052604090205460ff16600281111561114b57fe5b1461119d576040805162461bcd60e51b815260206004820152601e60248201527f435661756c74466f724c503a20706f6f6c206e6f742064697361626c65640000604482015290519081900360640190fd5b6001600160a01b0381166111f8576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f725472616465723a20696e76616c696420706f6f6c000000604482015290519081900360640190fd5b6001600160a01b038116600090815260086020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915560075461124891611e9a565b6007819055506000816001600160a01b03166372f702f36040518163ffffffff1660e01b815260040160206040518083038186803b15801561128957600080fd5b505afa15801561129d573d6000803e3d6000fd5b505050506040513d60208110156112b357600080fd5b50516001600160a01b038082166000908152600960205260409020549192501615611325576040805162461bcd60e51b815260206004820152601760248201527f435661756c74466f724c503a2070616972206164646564000000000000000000604482015290519081900360640190fd5b6001600160a01b0381811660009081526009602090815260409182902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169386169384179055815192835290517ff37bc7d2dc2b5bd3afd83f8325fd7f602d73391cc33915689bea4c61f81b12d99281900390910190a15050565b6002546001600160a01b031681565b7f000000000000000000000000000000000000000000000000000000000000000081565b600754600090806113eb576000915050610de1565b60006113f561142c565b6001600160a01b03851660009081526008602052604090206001015490915061142360646107148484611ef4565b95945050505050565b6000806114376106f7565b90506004811115611446575060045b60035460055460005b838110156114705761146660646107148585611ef4565b925060010161144f565b50909250505090565b6008602052600090815260409020805460019091015460ff9091169082565b3360009081526008602052604081205460ff16818160028111156114b857fe5b14806114cf575060028160028111156114cd57fe5b145b156114de576000915050610de1565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b58aa4786040518163ffffffff1660e01b815260040160206040518083038186803b15801561153957600080fd5b505afa15801561154d573d6000803e3d6000fd5b505050506040513d602081101561156357600080fd5b505190506001600160a01b03811661158057600092505050610de1565b6000816001600160a01b031663a66771db866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156115cf57600080fd5b505afa1580156115e3573d6000803e3d6000fd5b505050506040513d60208110156115f957600080fd5b505195945050505050565b60055481565b6002546001600160a01b03163314611669576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e8a353926040518163ffffffff1660e01b815260040160206040518083038186803b1580156116fe57600080fd5b505afa158015611712573d6000803e3d6000fd5b505050506040513d602081101561172857600080fd5b5051905090565b6002546001600160a01b0316331461178e576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b600355565b7f000000000000000000000000000000000000000000000000000000000000000081565b6009602052600090815260409020546001600160a01b031681565b6001600160a01b0380821660009081526009602052604081205490918291166117fa8161071f565b9250925050915091565b6002546001600160a01b03163314611863576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b6001600160a01b03811660009081526008602052604081205460ff16600281111561188a57fe5b146118dc576040805162461bcd60e51b815260206004820152601760248201527f435661756c74466f724c503a20706f6f6c206164646564000000000000000000604482015290519081900360640190fd5b6001600160a01b038116611937576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f725472616465723a20696e76616c696420706f6f6c000000604482015290519081900360640190fd5b6001600160a01b038116600090815260086020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915560075461198791611e9a565b6007819055506000816001600160a01b03166372f702f36040518163ffffffff1660e01b815260040160206040518083038186803b1580156119c857600080fd5b505afa1580156119dc573d6000803e3d6000fd5b505050506040513d60208110156119f257600080fd5b50516001600160a01b038082166000908152600960205260409020549192501615611a64576040805162461bcd60e51b815260206004820152601760248201527f435661756c74466f724c503a2070616972206164646564000000000000000000604482015290519081900360640190fd5b6001600160a01b03808216600090815260096020908152604080832080549487167fffffffffffffffffffffffff0000000000000000000000000000000000000000958616811790915560068054600181018255948190527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f90940180549095168117909455915482519384529083015280517f38bff197ec9fef6e32271789b78dca0f10af5b2b546ce690a67899f608ba4f4c9281900390910190a15050565b6002546001600160a01b03163314611b84576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b60016001600160a01b03821660009081526008602052604090205460ff166002811115611bad57fe5b14611bff576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f724c503a20706f6f6c206e6f7420656e61626c6564000000604482015290519081900360640190fd5b6001600160a01b038116611c5a576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f725472616465723a20696e76616c696420706f6f6c000000604482015290519081900360640190fd5b6001600160a01b038116600090815260086020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166002178155600190810191909155600754611cb091611dd1565b6007819055506000816001600160a01b03166372f702f36040518163ffffffff1660e01b815260040160206040518083038186803b158015611cf157600080fd5b505afa158015611d05573d6000803e3d6000fd5b505050506040513d6020811015611d1b57600080fd5b50516001600160a01b0380821660009081526009602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690558151928616835290519293507ff82ae9a5785e9b261d7e8bba20ced7516919ec7bdc4b18e7d916316f4991e53292918290030190a15050565b606481565b6001600160a01b03808216600090815260096020526040812054909116611dc4816113d6565b9392505050565b60075481565b600082821115611e28576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b6000808211611e89576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611e9257fe5b049392505050565b600082820183811015611dc4576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082611f0357506000611e2d565b82820282848281611f1057fe5b0414611dc45760405162461bcd60e51b8152600401808060200182810382526021815260200180611f4e6021913960400191505060405180910390fdfe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77435661756c74466f724c503a2077726f6e6720706572696f642073657474696e67a264697066735822122079f6823a63a0124595f6ec3c32c41e176490abfe20eb6b5f586d204ebcfdb6f264736f6c634300060c00330000000000000000000000001a23a6bfbadb59fa563008c0fb7cf96dfcf34ea100000000000000000000000039816b841436a57729723d9da127805755d2cb51

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061020b5760003560e01c80635d941dd51161012a578063b26acd7a116100bd578063d914cd4b1161008c578063defe80ef11610071578063defe80ef1461065d578063e665cfe014610665578063f8a6d78f1461068b5761020b565b8063d914cd4b14610611578063dcaaa61b146106375761020b565b8063b26acd7a146105a0578063c45a0155146105bd578063cc28ac6a146105c5578063cc442f7c146105eb5761020b565b8063a66771db116100f9578063a66771db14610544578063a9c1f2f11461056a578063ab033ea914610572578063af1734ac146105985761020b565b80635d941dd5146104e8578063643a8b24146104f057806379d5d863146105165780639a7b5f111461051e5761020b565b806338d8294b116101a25780634cdc9c63116101715780634cdc9c63146104aa57806355d9cdff146104b2578063595aeb50146104ba5780635aa6e675146104e05761020b565b806338d8294b1461031c5780633be8b7681461035e57806341d1de971461048557806348d67e1b146104a25761020b565b80630c5890a0116101de5780630c5890a0146102c35780631ec8bb8c146102cb57806324de74bd146102f7578063342f802b146102ff5761020b565b806304e7e0b914610210578063060406181461022f57806306bfa9381461024957806307ec6c8114610297575b600080fd5b61022d6004803603602081101561022657600080fd5b5035610693565b005b6102376106f7565b60408051918252519081900360200190f35b61026f6004803603602081101561025f57600080fd5b50356001600160a01b031661071f565b6040518083600281111561027f57fe5b81526020018281526020019250505060405180910390f35b61022d600480360360408110156102ad57600080fd5b506001600160a01b038135169060200135610746565b6102376108f0565b61022d600480360360408110156102e157600080fd5b506001600160a01b0381351690602001356108f6565b610237610d1f565b61022d6004803603602081101561031557600080fd5b5035610d25565b6103426004803603602081101561033257600080fd5b50356001600160a01b0316610dc5565b604080516001600160a01b039092168252519081900360200190f35b61022d6004803603604081101561037457600080fd5b81019060208101813564010000000081111561038f57600080fd5b8201836020820111156103a157600080fd5b803590602001918460208302840111640100000000831117156103c357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561041357600080fd5b82018360208201111561042557600080fd5b8035906020019184602083028401116401000000008311171561044757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610de6945050505050565b6103426004803603602081101561049b57600080fd5b5035611087565b6102376110ae565b6102376110b4565b61022d6110ba565b61022d600480360360208110156104d057600080fd5b50356001600160a01b03166110c3565b6103426113a3565b6103426113b2565b6102376004803603602081101561050657600080fd5b50356001600160a01b03166113d6565b61023761142c565b61026f6004803603602081101561053457600080fd5b50356001600160a01b0316611479565b6102376004803603602081101561055a57600080fd5b50356001600160a01b0316611498565b610237611604565b61022d6004803603602081101561058857600080fd5b50356001600160a01b031661160a565b6103426116a3565b61022d600480360360208110156105b657600080fd5b503561172f565b610342611793565b610342600480360360208110156105db57600080fd5b50356001600160a01b03166117b7565b61026f6004803603602081101561060157600080fd5b50356001600160a01b03166117d2565b61022d6004803603602081101561062757600080fd5b50356001600160a01b0316611804565b61022d6004803603602081101561064d57600080fd5b50356001600160a01b0316611b25565b610237611d99565b6102376004803603602081101561067b57600080fd5b50356001600160a01b0316611d9e565b610237611dcb565b6002546001600160a01b031633146106f2576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b600555565b600061071a60045461071460015443611dd190919063ffffffff16565b90611e33565b905090565b6001600160a01b03166000908152600860205260409020805460019091015460ff90911691565b6002546001600160a01b031633146107a5576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b60648111156107fb576040805162461bcd60e51b815260206004820152601b60248201527f435661756c74466f724c503a20696e76616c6964207765696768740000000000604482015290519081900360640190fd5b6001600160a01b038216610856576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f725472616465723a20696e76616c696420706f6f6c000000604482015290519081900360640190fd5b60016001600160a01b03831660009081526008602052604090205460ff16600281111561087f57fe5b146108d1576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f724c503a20706f6f6c206e6f7420656e61626c6564000000604482015290519081900360640190fd5b6001600160a01b03909116600090815260086020526040902060010155565b60035481565b6002600054141561094e576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260009081553381526008602052604081205460ff169081600281111561097257fe5b14156109c5576040805162461bcd60e51b815260206004820152601c60248201527f435661756c74466f724c503a206f6e6c7920706f6f6c2076616c696400000000604482015290519081900360640190fd5b60028160028111156109d357fe5b14156109df5750610d16565b6001600160a01b038316610a3a576040805162461bcd60e51b815260206004820152601b60248201527f435661756c74466f725472616465723a20696e76616c696420746f0000000000604482015290519081900360640190fd5b60007f00000000000000000000000039816b841436a57729723d9da127805755d2cb516001600160a01b031663b58aa4786040518163ffffffff1660e01b815260040160206040518083038186803b158015610a9557600080fd5b505afa158015610aa9573d6000803e3d6000fd5b505050506040513d6020811015610abf57600080fd5b505190506001600160a01b03811615610c84576000336001600160a01b03166372f702f36040518163ffffffff1660e01b815260040160206040518083038186803b158015610b0d57600080fd5b505afa158015610b21573d6000803e3d6000fd5b505050506040513d6020811015610b3757600080fd5b505190506001600160a01b038116610b96576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f725472616465723a20696e76616c69642070616972000000604482015290519081900360640190fd5b6000826001600160a01b031663a66771db836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610be557600080fd5b505afa158015610bf9573d6000803e3d6000fd5b505050506040513d6020811015610c0f57600080fd5b505190508015610c8157826001600160a01b0316633d1b7dcc836040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050600060405180830381600087803b158015610c6857600080fd5b505af1158015610c7c573d6000803e3d6000fd5b505050505b50505b7f0000000000000000000000001a23a6bfbadb59fa563008c0fb7cf96dfcf34ea16001600160a01b03166340c10f1985856040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015610cfb57600080fd5b505af1158015610d0f573d6000803e3d6000fd5b5050505050505b50506001600055565b60075490565b6002546001600160a01b03163314610d84576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b80610dc05760405162461bcd60e51b8152600401808060200182810382526021815260200180611f6f6021913960400191505060405180910390fd5b600455565b6001600160a01b03808216600090815260096020526040902054165b919050565b6002546001600160a01b03163314610e45576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b815181518114610e9c576040805162461bcd60e51b815260206004820152601960248201527f435661756c74466f724c503a206d69736d61746368206c656e00000000000000604482015290519081900360640190fd5b60005b818110156110815760006001600160a01b0316848281518110610ebe57fe5b60200260200101516001600160a01b03161415610f22576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f725472616465723a20696e76616c696420706f6f6c000000604482015290519081900360640190fd5b6064838281518110610f3057fe5b60200260200101511115610f8b576040805162461bcd60e51b815260206004820152601b60248201527f435661756c74466f724c503a20696e76616c6964207765696768740000000000604482015290519081900360640190fd5b600160086000868481518110610f9d57fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff166002811115610fcf57fe5b14611021576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f724c503a20706f6f6c206e6f7420656e61626c6564000000604482015290519081900360640190fd5b82818151811061102d57fe5b60200260200101516008600086848151811061104557fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600101819055508080600101915050610e9f565b50505050565b6006818154811061109457fe5b6000918252602090912001546001600160a01b0316905081565b60045481565b60015481565b62a877b0600155565b6002546001600160a01b03163314611122576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b60026001600160a01b03821660009081526008602052604090205460ff16600281111561114b57fe5b1461119d576040805162461bcd60e51b815260206004820152601e60248201527f435661756c74466f724c503a20706f6f6c206e6f742064697361626c65640000604482015290519081900360640190fd5b6001600160a01b0381166111f8576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f725472616465723a20696e76616c696420706f6f6c000000604482015290519081900360640190fd5b6001600160a01b038116600090815260086020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915560075461124891611e9a565b6007819055506000816001600160a01b03166372f702f36040518163ffffffff1660e01b815260040160206040518083038186803b15801561128957600080fd5b505afa15801561129d573d6000803e3d6000fd5b505050506040513d60208110156112b357600080fd5b50516001600160a01b038082166000908152600960205260409020549192501615611325576040805162461bcd60e51b815260206004820152601760248201527f435661756c74466f724c503a2070616972206164646564000000000000000000604482015290519081900360640190fd5b6001600160a01b0381811660009081526009602090815260409182902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169386169384179055815192835290517ff37bc7d2dc2b5bd3afd83f8325fd7f602d73391cc33915689bea4c61f81b12d99281900390910190a15050565b6002546001600160a01b031681565b7f0000000000000000000000001a23a6bfbadb59fa563008c0fb7cf96dfcf34ea181565b600754600090806113eb576000915050610de1565b60006113f561142c565b6001600160a01b03851660009081526008602052604090206001015490915061142360646107148484611ef4565b95945050505050565b6000806114376106f7565b90506004811115611446575060045b60035460055460005b838110156114705761146660646107148585611ef4565b925060010161144f565b50909250505090565b6008602052600090815260409020805460019091015460ff9091169082565b3360009081526008602052604081205460ff16818160028111156114b857fe5b14806114cf575060028160028111156114cd57fe5b145b156114de576000915050610de1565b60007f00000000000000000000000039816b841436a57729723d9da127805755d2cb516001600160a01b031663b58aa4786040518163ffffffff1660e01b815260040160206040518083038186803b15801561153957600080fd5b505afa15801561154d573d6000803e3d6000fd5b505050506040513d602081101561156357600080fd5b505190506001600160a01b03811661158057600092505050610de1565b6000816001600160a01b031663a66771db866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156115cf57600080fd5b505afa1580156115e3573d6000803e3d6000fd5b505050506040513d60208110156115f957600080fd5b505195945050505050565b60055481565b6002546001600160a01b03163314611669576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b60007f00000000000000000000000039816b841436a57729723d9da127805755d2cb516001600160a01b031663e8a353926040518163ffffffff1660e01b815260040160206040518083038186803b1580156116fe57600080fd5b505afa158015611712573d6000803e3d6000fd5b505050506040513d602081101561172857600080fd5b5051905090565b6002546001600160a01b0316331461178e576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b600355565b7f00000000000000000000000039816b841436a57729723d9da127805755d2cb5181565b6009602052600090815260409020546001600160a01b031681565b6001600160a01b0380821660009081526009602052604081205490918291166117fa8161071f565b9250925050915091565b6002546001600160a01b03163314611863576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b6001600160a01b03811660009081526008602052604081205460ff16600281111561188a57fe5b146118dc576040805162461bcd60e51b815260206004820152601760248201527f435661756c74466f724c503a20706f6f6c206164646564000000000000000000604482015290519081900360640190fd5b6001600160a01b038116611937576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f725472616465723a20696e76616c696420706f6f6c000000604482015290519081900360640190fd5b6001600160a01b038116600090815260086020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915560075461198791611e9a565b6007819055506000816001600160a01b03166372f702f36040518163ffffffff1660e01b815260040160206040518083038186803b1580156119c857600080fd5b505afa1580156119dc573d6000803e3d6000fd5b505050506040513d60208110156119f257600080fd5b50516001600160a01b038082166000908152600960205260409020549192501615611a64576040805162461bcd60e51b815260206004820152601760248201527f435661756c74466f724c503a2070616972206164646564000000000000000000604482015290519081900360640190fd5b6001600160a01b03808216600090815260096020908152604080832080549487167fffffffffffffffffffffffff0000000000000000000000000000000000000000958616811790915560068054600181018255948190527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f90940180549095168117909455915482519384529083015280517f38bff197ec9fef6e32271789b78dca0f10af5b2b546ce690a67899f608ba4f4c9281900390910190a15050565b6002546001600160a01b03163314611b84576040805162461bcd60e51b815260206004820152601860248201527f435661756c74466f724c503a2021676f7665726e616e63650000000000000000604482015290519081900360640190fd5b60016001600160a01b03821660009081526008602052604090205460ff166002811115611bad57fe5b14611bff576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f724c503a20706f6f6c206e6f7420656e61626c6564000000604482015290519081900360640190fd5b6001600160a01b038116611c5a576040805162461bcd60e51b815260206004820152601d60248201527f435661756c74466f725472616465723a20696e76616c696420706f6f6c000000604482015290519081900360640190fd5b6001600160a01b038116600090815260086020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166002178155600190810191909155600754611cb091611dd1565b6007819055506000816001600160a01b03166372f702f36040518163ffffffff1660e01b815260040160206040518083038186803b158015611cf157600080fd5b505afa158015611d05573d6000803e3d6000fd5b505050506040513d6020811015611d1b57600080fd5b50516001600160a01b0380821660009081526009602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690558151928616835290519293507ff82ae9a5785e9b261d7e8bba20ced7516919ec7bdc4b18e7d916316f4991e53292918290030190a15050565b606481565b6001600160a01b03808216600090815260096020526040812054909116611dc4816113d6565b9392505050565b60075481565b600082821115611e28576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b6000808211611e89576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611e9257fe5b049392505050565b600082820183811015611dc4576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082611f0357506000611e2d565b82820282848281611f1057fe5b0414611dc45760405162461bcd60e51b8152600401808060200182810382526021815260200180611f4e6021913960400191505060405180910390fdfe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77435661756c74466f724c503a2077726f6e6720706572696f642073657474696e67a264697066735822122079f6823a63a0124595f6ec3c32c41e176490abfe20eb6b5f586d204ebcfdb6f264736f6c634300060c0033

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

0000000000000000000000001a23a6bfbadb59fa563008c0fb7cf96dfcf34ea100000000000000000000000039816b841436a57729723d9da127805755d2cb51

-----Decoded View---------------
Arg [0] : cofi (address): 0x1a23a6BfBAdB59fa563008c0fB7cf96dfCF34Ea1
Arg [1] : _factory (address): 0x39816B841436a57729723d9DA127805755d2CB51

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000001a23a6bfbadb59fa563008c0fb7cf96dfcf34ea1
Arg [1] : 00000000000000000000000039816b841436a57729723d9da127805755d2cb51


Deployed Bytecode Sourcemap

48906:9271:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50825:104;;;;;;;;;;;;;;;;-1:-1:-1;50825:104:0;;:::i;:::-;;56082:139;;;:::i;:::-;;;;;;;;;;;;;;;;57449:220;;;;;;;;;;;;;;;;-1:-1:-1;57449:220:0;-1:-1:-1;;;;;57449:220:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53015:409;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;53015:409:0;;;;;;;;:::i;49296:38::-;;;:::i;54889:1185::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;54889:1185:0;;;;;;;;:::i;57915:106::-;;;:::i;50643:174::-;;;;;;;;;;;;;;;;-1:-1:-1;50643:174:0;;:::i;57304:137::-;;;;;;;;;;;;;;;;-1:-1:-1;57304:137:0;-1:-1:-1;;;;;57304:137:0;;:::i;:::-;;;;-1:-1:-1;;;;;57304:137:0;;;;;;;;;;;;;;53432:707;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53432:707:0;;;;;;;;-1:-1:-1;53432:707:0;;-1:-1:-1;;53432:707:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53432:707:0;;-1:-1:-1;53432:707:0;;-1:-1:-1;;;;;53432:707:0:i;49504:25::-;;;;;;;;;;;;;;;;-1:-1:-1;49504:25:0;;:::i;49380:36::-;;;:::i;49196:27::-;;;:::i;50268:92::-;;;:::i;51737:663::-;;;;;;;;;;;;;;;;-1:-1:-1;51737:663:0;-1:-1:-1;;;;;51737:663:0;;:::i;49262:25::-;;;:::i;49114:34::-;;;:::i;56697:370::-;;;;;;;;;;;;;;;;-1:-1:-1;56697:370:0;-1:-1:-1;;;;;56697:370:0;;:::i;56229:460::-;;;:::i;49714:45::-;;;;;;;;;;;;;;;;-1:-1:-1;49714:45:0;-1:-1:-1;;;;;49714:45:0;;:::i;54151:730::-;;;;;;;;;;;;;;;;-1:-1:-1;54151:730:0;-1:-1:-1;;;;;54151:730:0;;:::i;49466:29::-;;;:::i;50411:106::-;;;;;;;;;;;;;;;;-1:-1:-1;50411:106:0;-1:-1:-1;;;;;50411:106:0;;:::i;58029:143::-;;;:::i;50525:110::-;;;;;;;;;;;;;;;;-1:-1:-1;50525:110:0;;:::i;49155:32::-;;;:::i;49788:53::-;;;;;;;;;;;;;;;;-1:-1:-1;49788:53:0;-1:-1:-1;;;;;49788:53:0;;:::i;57677:199::-;;;;;;;;;;;;;;;;-1:-1:-1;57677:199:0;-1:-1:-1;;;;;57677:199:0;;:::i;50937:792::-;;;;;;;;;;;;;;;;-1:-1:-1;50937:792:0;-1:-1:-1;;;;;50937:792:0;;:::i;52408:599::-;;;;;;;;;;;;;;;;-1:-1:-1;52408:599:0;-1:-1:-1;;;;;52408:599:0;;:::i;49064:41::-;;;:::i;57075:221::-;;;;;;;;;;;;;;;;-1:-1:-1;57075:221:0;-1:-1:-1;;;;;57075:221:0;;:::i;49596:25::-;;;:::i;50825:104::-;49933:10;;-1:-1:-1;;;;;49933:10:0;49919;:24;49911:61;;;;;-1:-1:-1;;;49911:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;50905:9:::1;:16:::0;50825:104::o;56082:139::-;56137:7;56164:49;56201:11;;56164:32;56183:12;;56165;56164:18;;:32;;;;:::i;:::-;:36;;:49::i;:::-;56157:56;;56082:139;:::o;57449:220::-;-1:-1:-1;;;;;57567:14:0;57514:16;57567:14;;;:8;:14;;;;;:20;;;57607:21;;;;57567:20;;;;;57449:220::o;53015:409::-;49933:10;;-1:-1:-1;;;;;49933:10:0;49919;:24;49911:61;;;;;-1:-1:-1;;;49911:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;49102:3:::1;53118:6;:21;;53110:61;;;::::0;;-1:-1:-1;;;53110:61:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;53190:18:0;::::1;53182:60;;;::::0;;-1:-1:-1;;;53182:60:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;53285:18;-1:-1:-1::0;;;;;53261:14:0;::::1;;::::0;;;:8:::1;:14;::::0;;;;:20;::::1;;:42;::::0;::::1;;;;;;;53253:84;;;::::0;;-1:-1:-1;;;53253:84:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;53386:14:0;;::::1;;::::0;;;:8:::1;:14;::::0;;;;:21:::1;;:30:::0;53015:409::o;49296:38::-;;;;:::o;54889:1185::-;5708:1;6314:7;;:19;;6306:63;;;;;-1:-1:-1;;;6306:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;5708:1;6447:7;:18;;;55017:10:::1;55008:20:::0;;:8:::1;:20;::::0;;;;:26;::::1;;::::0;55053:9:::1;:31;;;;;;;;;;55045:72;;;::::0;;-1:-1:-1;;;55045:72:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;55145:19;55132:9;:32;;;;;;;;;55128:150;;;55181:7;;;55128:150;-1:-1:-1::0;;;;;55296:16:0;::::1;55288:56;;;::::0;;-1:-1:-1;;;55288:56:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;55445:22;55486:7;-1:-1:-1::0;;;;;55470:42:0::1;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;55470:44:0;;-1:-1:-1;;;;;;55529:28:0;::::1;::::0;55525:478:::1;;55623:12;55659:10;-1:-1:-1::0;;;;;55638:45:0::1;;:47;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;55638:47:0;;-1:-1:-1;;;;;;55708:18:0;::::1;55700:60;;;::::0;;-1:-1:-1;;;55700:60:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;55775:15;55816:14;-1:-1:-1::0;;;;;55793:59:0::1;;55853:4;55793:65;;;;;;;;;;;;;-1:-1:-1::0;;;;;55793:65:0::1;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;55793:65:0;;-1:-1:-1;55877:11:0;;55873:119:::1;;55932:14;-1:-1:-1::0;;;;;55909:61:0::1;;55971:4;55909:67;;;;;;;;;;;;;-1:-1:-1::0;;;;;55909:67:0::1;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;55873:119;55525:478;;;56024:9;-1:-1:-1::0;;;;;56013:26:0::1;;56040:2;56044:6;56013:38;;;;;;;;;;;;;-1:-1:-1::0;;;;;56013:38:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;6478:1;;;-1:-1:-1::0;;5664:1:0;6626:7;:22;54889:1185::o;57915:106::-;58003:10;;57915:106;:::o;50643:174::-;49933:10;;-1:-1:-1;;;;;49933:10:0;49919;:24;49911:61;;;;;-1:-1:-1;;;49911:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;50733:9;50725:55:::1;;;;-1:-1:-1::0;;;50725:55:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50791:11;:18:::0;50643:174::o;57304:137::-;-1:-1:-1;;;;;57410:23:0;;;57378:12;57410:23;;;:17;:23;;;;;;;57304:137;;;;:::o;53432:707::-;49933:10;;-1:-1:-1;;;;;49933:10:0;49919;:24;49911:61;;;;;-1:-1:-1;;;49911:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53568:12;;53606:14;;53599:21;::::1;53591:59;;;::::0;;-1:-1:-1;;;53591:59:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;53666:9;53661:399;53685:3;53681:1;:7;53661:399;;;53738:1;-1:-1:-1::0;;;;;53718:22:0::1;:5;53724:1;53718:8;;;;;;;;;;;;;;-1:-1:-1::0;;;;;53718:22:0::1;;;53710:64;;;::::0;;-1:-1:-1;;;53710:64:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;49102:3;53797:7;53805:1;53797:10;;;;;;;;;;;;;;:25;;53789:65;;;::::0;;-1:-1:-1;;;53789:65:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;53905:18;53877:8;:18;53886:5;53892:1;53886:8;;;;;;;;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;53877:18:0::1;::::0;;;::::1;::::0;;;;;;-1:-1:-1;53877:18:0;:24;::::1;;:46;::::0;::::1;;;;;;;53869:88;;;::::0;;-1:-1:-1;;;53869:88:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;54038:7;54046:1;54038:10;;;;;;;;;;;;;;54010:8;:18;54019:5;54025:1;54019:8;;;;;;;;;;;;;;-1:-1:-1::0;;;;;54010:18:0::1;-1:-1:-1::0;;;;;54010:18:0::1;;;;;;;;;;;;:25;;:38;;;;53690:3;;;;;;;53661:399;;;;49983:1;53432:707:::0;;:::o;49504:25::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;49504:25:0;;-1:-1:-1;49504:25:0;:::o;49380:36::-;;;;:::o;49196:27::-;;;;:::o;50268:92::-;50330:8;50315:12;:23;50268:92::o;51737:663::-;49933:10;;-1:-1:-1;;;;;49933:10:0;49919;:24;49911:61;;;;;-1:-1:-1;;;49911:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;51847:19:::1;-1:-1:-1::0;;;;;51823:14:0;::::1;;::::0;;;:8:::1;:14;::::0;;;;:20;::::1;;:43;::::0;::::1;;;;;;;51815:86;;;::::0;;-1:-1:-1;;;51815:86:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;51943:18:0;::::1;51935:60;;;::::0;;-1:-1:-1;;;51935:60:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;52006:14:0;::::1;;::::0;;;:8:::1;:14;::::0;;;;:41;;;::::1;52029:18;52006:41:::0;;::::1;::::0;;;52071:10:::1;::::0;:17:::1;::::0;:14:::1;:17::i;:::-;52058:10;:30;;;;52139:12;52175:4;-1:-1:-1::0;;;;;52154:39:0::1;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;52154:41:0;-1:-1:-1;;;;;52214:23:0;;::::1;52249:1;52214:23:::0;;;:17:::1;52154:41;52214:23:::0;;;;;52154:41;;-1:-1:-1;52214:23:0::1;:37:::0;52206:73:::1;;;::::0;;-1:-1:-1;;;52206:73:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;52290:23:0;;::::1;;::::0;;;:17:::1;:23;::::0;;;;;;;;:30;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;52375:17;;;;;;;::::1;::::0;;;;;;;;::::1;49983:1;51737:663:::0;:::o;49262:25::-;;;-1:-1:-1;;;;;49262:25:0;;:::o;49114:34::-;;;:::o;56697:370::-;56809:10;;56766:16;;56834:8;56830:49;;56866:1;56859:8;;;;;56830:49;56889:16;56908:17;:15;:17::i;:::-;-1:-1:-1;;;;;56953:14:0;;56936;56953;;;:8;:14;;;;;:21;;;56889:36;;-1:-1:-1;56996:37:0;49102:3;56996:20;56889:36;56953:21;56996:12;:20::i;:37::-;56985:48;56697:370;-1:-1:-1;;;;;56697:370:0:o;56229:460::-;56286:7;56306:17;56326:15;:13;:15::i;:::-;56306:35;;56368:1;56356:9;:13;56352:100;;;-1:-1:-1;56398:1:0;56352:100;56481:12;;56525:9;;56462:16;56545:111;56569:9;56565:1;:13;56545:111;;;56611:33;56640:3;56611:24;:8;56624:10;56611:12;:24::i;:33::-;56600:44;-1:-1:-1;56580:3:0;;56545:111;;;-1:-1:-1;56673:8:0;;-1:-1:-1;;;56229:460:0;:::o;49714:45::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;54151:730::-;54279:10;54227:7;54270:20;;;:8;:20;;;;;:26;;;54227:7;54311:9;:31;;;;;;;;;:67;;;-1:-1:-1;54359:19:0;54346:9;:32;;;;;;;;;54311:67;54307:208;;;54402:1;54395:8;;;;;54307:208;54573:22;54614:7;-1:-1:-1;;;;;54598:42:0;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54598:44:0;;-1:-1:-1;;;;;;54657:28:0;;54653:102;;54709:1;54702:8;;;;;;54653:102;54765:15;54806:14;-1:-1:-1;;;;;54783:59:0;;54843:4;54783:65;;;;;;;;;;;;;-1:-1:-1;;;;;54783:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54783:65:0;;54151:730;-1:-1:-1;;;;;54151:730:0:o;49466:29::-;;;;:::o;50411:106::-;49933:10;;-1:-1:-1;;;;;49933:10:0;49919;:24;49911:61;;;;;-1:-1:-1;;;49911:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;50492:10:::1;:17:::0;;;::::1;-1:-1:-1::0;;;;;50492:17:0;;;::::1;::::0;;;::::1;::::0;;50411:106::o;58029:143::-;58091:12;58139:7;-1:-1:-1;;;;;58123:39:0;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;58123:41:0;;-1:-1:-1;58029:143:0;:::o;50525:110::-;49933:10;;-1:-1:-1;;;;;49933:10:0;49919;:24;49911:61;;;;;-1:-1:-1;;;49911:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;50608:12:::1;:19:::0;50525:110::o;49155:32::-;;;:::o;49788:53::-;;;;;;;;;;;;-1:-1:-1;;;;;49788:53:0;;:::o;57677:199::-;-1:-1:-1;;;;;57810:23:0;;;57750:16;57810:23;;;:17;:23;;;;;;57750:16;;;;57810:23;57851:17;57810:23;57851:11;:17::i;:::-;57844:24;;;;;57677:199;;;:::o;50937:792::-;49933:10;;-1:-1:-1;;;;;49933:10:0;49919;:24;49911:61;;;;;-1:-1:-1;;;49911:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51020:14:0;::::1;51044:18;51020:14:::0;;;:8:::1;:14;::::0;;;;:20;::::1;;:42;::::0;::::1;;;;;;;51012:78;;;::::0;;-1:-1:-1;;;51012:78:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;51131:18:0;::::1;51123:60;;;::::0;;-1:-1:-1;;;51123:60:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;51194:14:0;::::1;;::::0;;;:8:::1;:14;::::0;;;;:41;;;::::1;51217:18;51194:41:::0;;::::1;::::0;;;51310:10:::1;::::0;:17:::1;::::0;:14:::1;:17::i;:::-;51297:10;:30;;;;51378:12;51414:4;-1:-1:-1::0;;;;;51393:39:0::1;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;51393:41:0;-1:-1:-1;;;;;51453:23:0;;::::1;51488:1;51453:23:::0;;;:17:::1;51393:41;51453:23:::0;;;;;51393:41;;-1:-1:-1;51453:23:0::1;:37:::0;51445:73:::1;;;::::0;;-1:-1:-1;;;51445:73:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;51529:23:0;;::::1;;::::0;;;:17:::1;:23;::::0;;;;;;;:30;;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;51609:8:::1;:19:::0;;51529:30;51609:19;::::1;::::0;;;;;;;;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;;51705:15;;51686:35;;;;;;;::::1;::::0;;;::::1;::::0;;;;;;;;::::1;49983:1;50937:792:::0;:::o;52408:599::-;49933:10;;-1:-1:-1;;;;;49933:10:0;49919;:24;49911:61;;;;;-1:-1:-1;;;49911:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52519:18:::1;-1:-1:-1::0;;;;;52495:14:0;::::1;;::::0;;;:8:::1;:14;::::0;;;;:20;::::1;;:42;::::0;::::1;;;;;;;52487:84;;;::::0;;-1:-1:-1;;;52487:84:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;52613:18:0;::::1;52605:60;;;::::0;;-1:-1:-1;;;52605:60:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;52676:14:0;::::1;;::::0;;;:8:::1;:14;::::0;;;;:42;;;::::1;52699:19;52676:42;::::0;;;52729:21;;::::1;:25:::0;;;;52806:10:::1;::::0;:17:::1;::::0;:14:::1;:17::i;:::-;52793:10;:30;;;;52834:12;52870:4;-1:-1:-1::0;;;;;52849:39:0::1;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;52849:41:0;-1:-1:-1;;;;;52901:23:0;;::::1;52935:1;52901:23:::0;;;:17:::1;52849:41;52901:23:::0;;;;;;;;:36;;;::::1;::::0;;52981:18;;;;::::1;::::0;;;;52849:41;;-1:-1:-1;52981:18:0::1;::::0;;;;;;;::::1;49983:1;52408:599:::0;:::o;49064:41::-;49102:3;49064:41;:::o;57075:221::-;-1:-1:-1;;;;;57196:23:0;;;57152:16;57196:23;;;:17;:23;;;;;;57152:16;;57196:23;57241:21;57196:23;57241:15;:21::i;:::-;57230:32;57075:221;-1:-1:-1;;;57075:221:0:o;49596:25::-;;;;:::o;44580:158::-;44638:7;44671:1;44666;:6;;44658:49;;;;;-1:-1:-1;;;44658:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44725:5:0;;;44580:158;;;;;:::o;45695:153::-;45753:7;45785:1;45781;:5;45773:44;;;;;-1:-1:-1;;;45773:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;45839:1;45835;:5;;;;;;;45695:153;-1:-1:-1;;;45695:153:0:o;44118:179::-;44176:7;44208:5;;;44232:6;;;;44224:46;;;;;-1:-1:-1;;;44224:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;44997:220;45055:7;45079:6;45075:20;;-1:-1:-1;45094:1:0;45087:8;;45075:20;45118:5;;;45122:1;45118;:5;:1;45142:5;;;;;:10;45134:56;;;;-1:-1:-1;;;45134:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Swarm Source

ipfs://79f6823a63a0124595f6ec3c32c41e176490abfe20eb6b5f586d204ebcfdb6f2

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  ]

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.