ETH Price: $3,501.70 (-0.22%)
Gas: 2 Gwei

Token

TETHER_Dividen_Tracker (TETHER_Dividend_Tracker)
 

Overview

Max Total Supply

3,029,430.818645505 TETHER_Dividend_Tracker

Holders

75

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 9 Decimals)

Balance
28,973.68837371 TETHER_Dividend_Tracker

Value
$0.00
0xc57dc92c087f3fe84275a7dba0e26a0ab4d58139
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
TETHER_DividendTracker

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-08-06
*/

// telegram: https://t.me/emfxt69d

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

contract ERC20 is Context, IERC20, IERC20Metadata {
    using SafeMath for uint256;

    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 9;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

        /*
            _tokengeneration is an internal function in ERC20.sol that is only called here to generate the total supply first time,
            and CANNOT be called ever again
        */
    function _tokengeneration(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: new tokens to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

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

        return c;
    }

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

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

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

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

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

/**
 * @title SafeMathInt
 * @dev Math operations for int256 with overflow safety checks.
 */
library SafeMathInt {
    int256 private constant MIN_INT256 = int256(1) << 255;
    int256 private constant MAX_INT256 = ~(int256(1) << 255);

    /**
     * @dev Multiplies two int256 variables and fails on overflow.
     */
    function mul(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a * b;

        // Detect overflow when multiplying MIN_INT256 with -1
        require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256));
        require((b == 0) || (c / b == a));
        return c;
    }

    /**
     * @dev Division of two int256 variables and fails on overflow.
     */
    function div(int256 a, int256 b) internal pure returns (int256) {
        // Prevent overflow when dividing MIN_INT256 by -1
        require(b != -1 || a != MIN_INT256);

        // Solidity already throws when dividing by 0.
        return a / b;
    }

    /**
     * @dev Subtracts two int256 variables and fails on overflow.
     */
    function sub(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a));
        return c;
    }

    /**
     * @dev Adds two int256 variables and fails on overflow.
     */
    function add(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a));
        return c;
    }

    /**
     * @dev Converts to absolute value, and fails on overflow.
     */
    function abs(int256 a) internal pure returns (int256) {
        require(a != MIN_INT256);
        return a < 0 ? -a : a;
    }


    function toUint256Safe(int256 a) internal pure returns (uint256) {
        require(a >= 0);
        return uint256(a);
    }
}

/**
 * @title SafeMathUint
 * @dev Math operations with safety checks that revert on error
 */
library SafeMathUint {
  function toInt256Safe(uint256 a) internal pure returns (int256) {
    int256 b = int256(a);
    require(b >= 0);
    return b;
  }
}

contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(_owner == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

interface IPair {
    function sync() external;
}

interface IFactory{
        function createPair(address tokenA, address tokenB) external returns (address pair);
        function getPair(address tokenA, address tokenB) external view returns (address pair);
}

interface IRouter {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);
    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
    
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
    
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline) external;
}

/// @title Dividend-Paying Token Interface
/// @author Roger Wu (https://github.com/roger-wu)
/// @dev An interface for a dividend-paying token contract.
interface DividendPayingTokenInterface {
  /// @notice View the amount of dividend in wei that an address can withdraw.
  /// @param _owner The address of a token holder.
  /// @return The amount of dividend in wei that `_owner` can withdraw.
  function dividendOf(address _owner) external view returns(uint256);
  
  function distributeDividends() external payable;
  
  /// @notice View the amount of dividend in wei that an address can withdraw.
  /// @param _owner The address of a token holder.
  /// @return The amount of dividend in wei that `_owner` can withdraw.
  function withdrawableDividendOf(address _owner) external view returns(uint256);

  /// @notice View the amount of dividend in wei that an address has withdrawn.
  /// @param _owner The address of a token holder.
  /// @return The amount of dividend in wei that `_owner` has withdrawn.
  function withdrawnDividendOf(address _owner) external view returns(uint256);

  /// @notice View the amount of dividend in wei that an address has earned in total.
  /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner)
  /// @param _owner The address of a token holder.
  /// @return The amount of dividend in wei that `_owner` has earned in total.
  function accumulativeDividendOf(address _owner) external view returns(uint256);


  /// @dev This event MUST emit when ether is distributed to token holders.
  /// @param from The address which sends ether to this contract.
  /// @param weiAmount The amount of distributed ether in wei.
  event DividendsDistributed(
    address indexed from,
    uint256 weiAmount
  );

  /// @dev This event MUST emit when an address withdraws their dividend.
  /// @param to The address which withdraws ether from this contract.
  /// @param weiAmount The amount of withdrawn ether in wei.
  event DividendWithdrawn(
    address indexed to,
    uint256 weiAmount
  );
  
}

contract DividendPayingToken is ERC20, DividendPayingTokenInterface, Ownable {
  using SafeMath for uint256;
  using SafeMathUint for uint256;
  using SafeMathInt for int256;

  // With `magnitude`, we can properly distribute dividends even if the amount of received ether is small.
  // For more discussion about choosing the value of `magnitude`,
  //  see https://github.com/ethereum/EIPs/issues/1726#issuecomment-472352728
  uint256 constant internal magnitude = 2**128;

  IRouter public router;
  address public rewardToken;

  uint256 internal magnifiedDividendPerShare;

  // About dividendCorrection:
  // If the token balance of a `_user` is never changed, the dividend of `_user` can be computed with:
  //   `dividendOf(_user) = dividendPerShare * balanceOf(_user)`.
  // When `balanceOf(_user)` is changed (via new tokens/burning/transferring tokens),
  //   `dividendOf(_user)` should not be changed,
  //   but the computed value of `dividendPerShare * balanceOf(_user)` is changed.
  // To keep the `dividendOf(_user)` unchanged, we add a correction term:
  //   `dividendOf(_user) = dividendPerShare * balanceOf(_user) + dividendCorrectionOf(_user)`,
  //   where `dividendCorrectionOf(_user)` is updated whenever `balanceOf(_user)` is changed:
  //   `dividendCorrectionOf(_user) = dividendPerShare * (old balanceOf(_user)) - (new balanceOf(_user))`.
  // So now `dividendOf(_user)` returns the same value before and after `balanceOf(_user)` is changed.
  mapping(address => int256) internal magnifiedDividendCorrections;
  mapping(address => uint256) internal withdrawnDividends;

  uint256 public totalDividendsDistributed;

  constructor(string memory _name, string memory _symbol)  ERC20(_name, _symbol) {
      IRouter _router = IRouter(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
      router = _router;
      rewardToken = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
  }

    /// @dev Distributes dividends whenever ether is paid to this contract.
    receive() external payable{
        distributeDividends();
    }

     function distributeDividends() public override payable {
      require(totalSupply() > 0);

      if (msg.value > 0) {
        magnifiedDividendPerShare = magnifiedDividendPerShare.add(
          (msg.value).mul(magnitude) / totalSupply()
        );
        emit DividendsDistributed(msg.sender, msg.value);

        totalDividendsDistributed = totalDividendsDistributed.add(msg.value);
      }
    }

    /// @notice Withdraws the ether distributed to the sender.
    /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.
    function _withdrawDividendOfUser(address payable user) internal returns (uint256) {
        uint256 _withdrawableDividend = withdrawableDividendOf(user);
        if (_withdrawableDividend > 0) {
            withdrawnDividends[user] = withdrawnDividends[user].add(_withdrawableDividend);
            emit DividendWithdrawn(user, _withdrawableDividend);
            if(rewardToken != router.WETH()){
                (bool success) = swapBnbForCustomToken(user, _withdrawableDividend);
                if(!success) {
                    (bool secondSuccess,) = user.call{value: _withdrawableDividend, gas: 3000}("");
                    if(!secondSuccess) {
                        withdrawnDividends[user] = withdrawnDividends[user].sub(_withdrawableDividend);
                        return 0;
                    }       
                }
            }
            else{
                (bool success,) = user.call{value: _withdrawableDividend, gas: 3000}("");
                if(!success) {
                    withdrawnDividends[user] = withdrawnDividends[user].sub(_withdrawableDividend);
                    return 0;
                }
            }
            return _withdrawableDividend;
        }
        return 0;
    }
    
    function setRewardToken(address newToken) external onlyOwner{
        rewardToken = newToken;
    }
  
    function swapBnbForCustomToken(address user, uint256 amt) internal returns (bool) {
          address[] memory path = new address[](2);
          path[0] = router.WETH();
          path[1] = rewardToken;

          try router.swapExactETHForTokens{value: amt}(0, path, user, block.timestamp + 2){
            return true;
        } catch {
            return false;
        }
    }

    /// @notice View the amount of dividend in wei that an address can withdraw.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` can withdraw.
    function dividendOf(address _owner) public view override returns(uint256) {
      return withdrawableDividendOf(_owner);
    }

    /// @notice View the amount of dividend in wei that an address can withdraw.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` can withdraw.
    function withdrawableDividendOf(address _owner) public view override returns(uint256) {
      return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]);
    }

    /// @notice View the amount of dividend in wei that an address has withdrawn.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` has withdrawn.
    function withdrawnDividendOf(address _owner) public view override returns(uint256) {
      return withdrawnDividends[_owner];
    }


    /// @notice View the amount of dividend in wei that an address has earned in total.
    /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner)
    /// = (magnifiedDividendPerShare * balanceOf(_owner) + magnifiedDividendCorrections[_owner]) / magnitude
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` has earned in total.
    function accumulativeDividendOf(address _owner) public view override returns(uint256) {
      return magnifiedDividendPerShare.mul(balanceOf(_owner)).toInt256Safe()
        .add(magnifiedDividendCorrections[_owner]).toUint256Safe() / magnitude;
    }

    /// @dev Internal function that transfer tokens from one address to another.
    /// Update magnifiedDividendCorrections to keep dividends unchanged.
    /// @param from The address to transfer from.
    /// @param to The address to transfer to.
    /// @param value The amount to be transferred.
    function _transfer(address from, address to, uint256 value) internal virtual override {
      require(false);

      int256 _magCorrection = magnifiedDividendPerShare.mul(value).toInt256Safe();
      magnifiedDividendCorrections[from] = magnifiedDividendCorrections[from].add(_magCorrection);
      magnifiedDividendCorrections[to] = magnifiedDividendCorrections[to].sub(_magCorrection);
    }

    /// Update magnifiedDividendCorrections to keep dividends unchanged.
    /// @param account The account that will receive the created tokens.
    /// @param value The amount that will be created.
    function _tokengeneration(address account, uint256 value) internal override {
      super._tokengeneration(account, value);

      magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account]
        .sub( (magnifiedDividendPerShare.mul(value)).toInt256Safe() );
    }

    /// @dev Internal function that burns an amount of the token of a given account.
    /// Update magnifiedDividendCorrections to keep dividends unchanged.
    /// @param account The account whose tokens will be burnt.
    /// @param value The amount that will be burnt.
    function _burn(address account, uint256 value) internal override {
      super._burn(account, value);

      magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account]
        .add( (magnifiedDividendPerShare.mul(value)).toInt256Safe() );
    }

    function _setBalance(address account, uint256 newBalance) internal {
      uint256 currentBalance = balanceOf(account);

      if(newBalance > currentBalance) {
        uint256 rewardtokensAmount = newBalance.sub(currentBalance);
        _tokengeneration(account, rewardtokensAmount);
      } else if(newBalance < currentBalance) {
        uint256 burnAmount = currentBalance.sub(newBalance);
        _burn(account, burnAmount);
      }
    }
  }

library IterableMapping {
    // Iterable mapping from address to uint;
    struct Map {
        address[] keys;
        mapping(address => uint) values;
        mapping(address => uint) indexOf;
        mapping(address => bool) inserted;
    }

    function get(Map storage map, address key) public view returns (uint) {
        return map.values[key];
    }

    function getIndexOfKey(Map storage map, address key) public view returns (int) {
        if(!map.inserted[key]) {
            return -1;
        }
        return int(map.indexOf[key]);
    }

    function getKeyAtIndex(Map storage map, uint index) public view returns (address) {
        return map.keys[index];
    }



    function size(Map storage map) public view returns (uint) {
        return map.keys.length;
    }

    function set(Map storage map, address key, uint val) public {
        if (map.inserted[key]) {
            map.values[key] = val;
        } else {
            map.inserted[key] = true;
            map.values[key] = val;
            map.indexOf[key] = map.keys.length;
            map.keys.push(key);
        }
    }

    function remove(Map storage map, address key) public {
        if (!map.inserted[key]) {
            return;
        }

        delete map.inserted[key];
        delete map.values[key];

        uint index = map.indexOf[key];
        uint lastIndex = map.keys.length - 1;
        address lastKey = map.keys[lastIndex];

        map.indexOf[lastKey] = index;
        delete map.indexOf[key];

        map.keys[index] = lastKey;
        map.keys.pop();
    }
}

library Address {
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }
}

contract ElonMuskFineXTrump69Doge is ERC20, Ownable {
    using Address for address payable;
    IRouter private  router;
    address private  pair;
    bool private swapping;
    bool private  swapEnabled = true;
    bool public tradingEnabled = false;
    uint256 private  startTradingBlock;
    TETHER_DividendTracker public dividendTracker;
    
    address public constant deadWallet = 0x000000000000000000000000000000000000dEaD;
    address private marketingWallet = 0x9EB9ea258655485B1E9d45fdC5164dB440C7A1c3;
    uint256 private swapTokensAtAmount = 2e5 * 10**9;
    uint256 public maxWalletBalance = 2e5 * 10**9;
    uint256 private maxBuyAmount = 2e5 * 10**9;
    uint256 private maxSellAmount = 2e5 * 10**9;
   
    string private currentRewardToken;

    struct Taxes {
        uint256 rewards;
        uint256 marketing;
        uint256 liquidity;
    }

    Taxes public buyTaxes = Taxes(1, 39, 0);
    Taxes public sellTaxes = Taxes(1, 39, 0);

    uint256 public gasForProcessing = 300000;
    uint256 private antiBotBlocks = 2;
    uint256 private launchtax = 99;
    
    mapping(address => bool) private _isExcludedFromFees;
    mapping(address => bool) public automatedMarketMakerPairs;

    event ExcludeFromFees(address indexed account, bool isExcluded);
    event ExcludeMultipleAccountsFromFees(address[] accounts, bool isExcluded);
    event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value);
    event GasForProcessingUpdated(uint256 indexed newValue, uint256 indexed oldValue);
    event SendDividends(uint256 tokensSwapped, uint256 amount);
    event ProcessedDividendTracker(
        uint256 iterations,
        uint256 claims,
        uint256 lastProcessedIndex,
        bool indexed automatic,
        uint256 gas,
        address indexed processor
    );

    constructor() ERC20("ElonMuskFineXTrump69Doge", "TETHER") {
        dividendTracker = new  TETHER_DividendTracker();
        IRouter _router = IRouter(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
        address _pair = IFactory(_router.factory()).createPair(address(this), _router.WETH());
        router = _router;
        pair = _pair;

        _setAutomatedMarketMakerPair(_pair, true);

        dividendTracker.excludeFromDividends(address(dividendTracker), true);
        dividendTracker.excludeFromDividends(address(this), true);
        dividendTracker.excludeFromDividends(owner(), true);
        dividendTracker.excludeFromDividends(deadWallet, true);
        dividendTracker.excludeFromDividends(address(_router), true);

        excludeFromFees(owner(), true);
        excludeFromFees(marketingWallet, true);
        excludeFromFees(address(this), true);

        _tokengeneration(owner(), 10000000 * (10**9));
    }

    receive() external payable {}

    function processDividendTracker(uint256 gas) external {
        (uint256 iterations, uint256 claims, uint256 lastProcessedIndex) = dividendTracker
            .process(gas);
        emit ProcessedDividendTracker(
            iterations,
            claims,
            lastProcessedIndex,
            false,
            gas,
            tx.origin
        );
    }

    function claim() external {
        dividendTracker.processAccount(payable(msg.sender), false);
    }

    function rescueERC20Tokens(address tokenAddress) external onlyOwner {
        require(tokenAddress != address(this), "Owner can't claim contract's balance of its own tokens");
        IERC20(tokenAddress).transfer(marketingWallet,IERC20(tokenAddress).balanceOf(address(this)));
    }

    function rescueETH() external {
        uint256 ETHbalance = address(this).balance;
        payable(marketingWallet).sendValue(ETHbalance);
    }

    function excludeFromFees(address account, bool excluded) public onlyOwner {
        require(
            _isExcludedFromFees[account] != excluded,
            "Account is already the value of 'excluded'"
        );
        _isExcludedFromFees[account] = excluded;

        emit ExcludeFromFees(account, excluded);
    }

    function excludeMultipleAccountsFromFees(address[] calldata accounts, bool excluded)
        public
        onlyOwner
    {
        for (uint256 i = 0; i < accounts.length; i++) {
            _isExcludedFromFees[accounts[i]] = excluded;
        }
        emit ExcludeMultipleAccountsFromFees(accounts, excluded);
    }

    /// @dev "true" to exlcude, "false" to include
    function excludeFromDividends(address account, bool value) external onlyOwner {
        dividendTracker.excludeFromDividends(account, value);
    }

    function setMaxTx(uint256 maxBuy, uint256 maxSell, uint256 maxWallet) external onlyOwner {
        require(maxBuy >= 1e4, "Cannot set max Buy amount lower than 0.1%");
        require(maxSell >= 1e4, "Cannot set max Sell amount lower than 0.1%");
        require(maxWallet >= 1e4, "Cannot set maxWallet lower than 0.1%");
        maxBuyAmount = maxBuy * 10**decimals();
        maxSellAmount = maxSell * 10**decimals();
        maxWalletBalance = maxWallet * 10**decimals();
     }

     function removeTxLimit() external onlyOwner{
        maxBuyAmount = 1e7 * 10**decimals();
        maxSellAmount = 1e7 * 10**decimals();
        maxWalletBalance = 1e7 * 10**decimals();
     }
    
    function setMarketinWallet(address newWallet) external onlyOwner {
        require(newWallet != address(this), "Fee Address cannot be Contract Address");
        require(newWallet != address(0),"Fee Address cannot be zero address");
        marketingWallet = newWallet;
       excludeFromFees(newWallet, true);
    }

    function setSwapTokensAtAmount(uint256 amount) external onlyOwner {
        require(amount >= 1e2, "amount must be greater than or equal to 0.001%");
        swapTokensAtAmount = amount * 10**9;
    }

    function setBuyTaxes(uint256 _rewards, uint256 marketing, uint256 _liquidity) external onlyOwner{
        buyTaxes = Taxes(_rewards, marketing, _liquidity);
        require((_rewards + marketing +  _liquidity ) <= 40, "Must keep fees at 40% or less");
    }

    function setSellTaxes(uint256 _rewards, uint256 marketing, uint256 _liquidity) external onlyOwner{
        sellTaxes = Taxes(_rewards, marketing, _liquidity);
        require((_rewards + marketing +  _liquidity ) <= 40, "Must keep fees at 40% or less");
    }

    function setSwapEnabled(bool _enabled) external onlyOwner {
        swapEnabled = _enabled;
    }    

    function enableTradingEnabled() external onlyOwner {
        require(!tradingEnabled, "Trading is already enabled");
        tradingEnabled = true;
        startTradingBlock = block.number;
    }

    function setMinBalanceForDividends(uint256 amount) external onlyOwner {
        dividendTracker.setMinBalanceForDividends(amount);
    }

    function _setAutomatedMarketMakerPair(address newPair, bool value) private {
        require(automatedMarketMakerPairs[newPair] != value,"Automated market maker pair is already set to that value");
        automatedMarketMakerPairs[newPair] = value;

        if (value) {
            dividendTracker.excludeFromDividends(newPair, true);
        }

        emit SetAutomatedMarketMakerPair(newPair, value);
    }

    /// @notice Update the gasForProcessing needed to auto-distribute rewards
    /// @param newValue The new amount of gas needed
    /// @dev The amount should not be greater than 500k to avoid expensive transactions
    function setGasForProcessing(uint256 newValue) external onlyOwner {
        require( newValue >= 200000 && newValue <= 500000,
           "GasForProcessing must be between 200,000 and 500,000"
        );
        require(newValue != gasForProcessing,
            "Cannot update gasForProcessing to same value"
        );
        emit GasForProcessingUpdated(newValue, gasForProcessing);
        gasForProcessing = newValue;
    }

    /// @dev Update the dividendTracker claimWait
    function setClaimWait(uint256 claimWait) external onlyOwner {
        dividendTracker.updateClaimWait(claimWait);
    }

    function getClaimWait() external view returns (uint256) {
        return dividendTracker.claimWait();
    }

    function getTotalDividendsDistributed() external view returns (uint256) {
        return dividendTracker.totalDividendsDistributed();
    }

    function isExcludedFromFees(address account) public view returns (bool) {
        return _isExcludedFromFees[account];
    }

    function withdrawableDividendOf(address account) public view returns (uint256) {
        return dividendTracker.withdrawableDividendOf(account);
    }

    function getCurrentRewardToken() external view returns (string memory) {
        return dividendTracker.getCurrentRewardToken();
    }

    function dividendTokenBalanceOf(address account) public view returns (uint256) {
        return dividendTracker.balanceOf(account);
    }

    function getAccountDividendsInfo(address account)
        external
        view
        returns (
            address,
            int256,
            int256,
            uint256,
            uint256,
            uint256,
            uint256,
            uint256
        )
    {
        return dividendTracker.getAccount(account);
    }

    function getAccountDividendsInfoAtIndex(uint256 index)
        external
        view
        returns (
            address,
            int256,
            int256,
            uint256,
            uint256,
            uint256,
            uint256,
            uint256
        )
    {
        return dividendTracker.getAccountAtIndex(index);
    }

    function getLastProcessedIndex() external view returns (uint256) {
        return dividendTracker.getLastProcessedIndex();
    }

    function getNumberOfDividendTokenHolders() external view returns (uint256) {
        return dividendTracker.getNumberOfTokenHolders();
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal override {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        if (!_isExcludedFromFees[from] && !_isExcludedFromFees[to]) {
                require(tradingEnabled, "Trading no active");
        }
       
        if (!automatedMarketMakerPairs[to] && !_isExcludedFromFees[from] && !_isExcludedFromFees[to]) {
                require( balanceOf(to) + (amount) <= maxWalletBalance,"Balance is exceeding maxWalletBalance" );
        }
             
        if (automatedMarketMakerPairs[from] && !_isExcludedFromFees[from] && !_isExcludedFromFees[to]) {
                require(amount <= maxBuyAmount, "You are exceeding maxBuyAmount");
        }
            
        if (!automatedMarketMakerPairs[from] && !_isExcludedFromFees[from] && !_isExcludedFromFees[to]) {
                require(amount <= maxSellAmount, "You are exceeding maxSellAmount");
        }
        if (amount == 0) {
            super._transfer(from, to, 0);
            return;
        }

        uint256 contractTokenBalance = balanceOf(address(this));
        bool canSwap = contractTokenBalance >= swapTokensAtAmount;
        uint256 swapTax = sellTaxes.rewards +
            sellTaxes.marketing +
            sellTaxes.liquidity ;

        if (
            canSwap &&
            !swapping &&
            swapEnabled &&
            !automatedMarketMakerPairs[from] &&
            !_isExcludedFromFees[from] &&
            !_isExcludedFromFees[to]
        ) {
            swapping = true;

            if (swapTax > 0) {
                swapAndLiquify(swapTokensAtAmount, swapTax);
            }

            swapping = false;
        }

        bool takeFee = !swapping;

        if (_isExcludedFromFees[from] || _isExcludedFromFees[to]) {
            takeFee = false;
        }
            if (takeFee) {
            bool useLaunchFee = block.number <= startTradingBlock + antiBotBlocks;
            uint256 swapAmt;
            
            if (automatedMarketMakerPairs[to] && !useLaunchFee) {
                swapAmt = (amount * swapTax) / 100;
            
            } else if (automatedMarketMakerPairs[from] && !useLaunchFee) {
                swapAmt =
                    (amount *
                        (buyTaxes.rewards +
                            buyTaxes.marketing +
                            buyTaxes.liquidity )) / 100;
            
            } else if (useLaunchFee) {
                swapAmt = (amount * launchtax) / 100; 
            }
            
            amount = amount - (swapAmt);
            super._transfer(from, address(this), swapAmt);
        }
        
        super._transfer(from, to, amount);
        
        try dividendTracker.setBalance(from, balanceOf(from)) {} catch {}
        try dividendTracker.setBalance(to, balanceOf(to)) {} catch {}

        if (!swapping) {
            uint256 gas = gasForProcessing;

            try dividendTracker.process(gas) returns (
                uint256 iterations,
                uint256 claims,
                uint256 lastProcessedIndex
            ) {
                emit ProcessedDividendTracker(
                    iterations,
                    claims,
                    lastProcessedIndex,
                    true,
                    gas,
                    tx.origin
                );
            } catch {}
        }
    }

    function swapAndLiquify(uint256 tokens, uint256 swapTax) private {
        uint256 denominator = swapTax * 2;
        uint256 tokensToAddLiquidityWith = (tokens * sellTaxes.liquidity) / denominator;
        uint256 toSwap = tokens - tokensToAddLiquidityWith;
        uint256 initialBalance = address(this).balance;
        swapTokensForBNB(toSwap);
        uint256 deltaBalance = address(this).balance - initialBalance;
        uint256 unitBalance = deltaBalance / (denominator - sellTaxes.liquidity);
        uint256 bnbToAddLiquidityWith = unitBalance * sellTaxes.liquidity;
        if (bnbToAddLiquidityWith > 0) {
            addLiquidity(tokensToAddLiquidityWith, bnbToAddLiquidityWith);
        }
        uint256 marketingWalletAmt = unitBalance * 2 * sellTaxes.marketing;
        if (marketingWalletAmt > 0) {
            payable(marketingWallet).sendValue(marketingWalletAmt);
        }
        uint256 dividends = unitBalance * 2 * sellTaxes.rewards;
        if (dividends > 0) {
            (bool success, ) = address(dividendTracker).call{ value: dividends }("");
            if (success) emit SendDividends(tokens, dividends);
        }
    }

    function swapTokensForBNB(uint256 tokenAmount) private {
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = router.WETH();
        _approve(address(this), address(router), tokenAmount);
        router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0, // accept any amount of ETH
            path,
            address(this),
            block.timestamp
        );
    }

    function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
        _approve(address(this), address(router), tokenAmount);
        router.addLiquidityETH{ value: ethAmount }(
            address(this),
            tokenAmount,
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            deadWallet,
            block.timestamp
        );
    }
}

contract TETHER_DividendTracker is Ownable, DividendPayingToken {
    using SafeMath for uint256;
    using SafeMathInt for int256;
    using IterableMapping for IterableMapping.Map;

    IterableMapping.Map private tokenHoldersMap;
    uint256 public lastProcessedIndex;

    mapping(address => bool) public excludedFromDividends;

    mapping(address => uint256) public lastClaimTimes;

    uint256 public claimWait;
    uint256 public minimumTokenBalanceForDividends;

    event ExcludeFromDividends(address indexed account, bool value);
    event ClaimWaitUpdated(uint256 indexed newValue, uint256 indexed oldValue);

    event Claim(address indexed account, uint256 amount, bool indexed automatic);

    constructor()
        DividendPayingToken("TETHER_Dividen_Tracker", "TETHER_Dividend_Tracker")
    {
        claimWait = 3600;
        minimumTokenBalanceForDividends = 1e3 * (10**decimals());
    }

    function _transfer(
        address,
        address,
        uint256
    ) internal pure override {
        require(false, "TETHER_Dividend_Tracker: No transfers allowed");
    }

    function setMinBalanceForDividends(uint256 amount) external onlyOwner {
        minimumTokenBalanceForDividends = amount * 10**decimals();
    }

    function excludeFromDividends(address account, bool value) external onlyOwner {
        require(excludedFromDividends[account] != value);
        excludedFromDividends[account] = value;
        if (value == true) {
            _setBalance(account, 0);
            tokenHoldersMap.remove(account);
        } else {
            _setBalance(account, balanceOf(account));
            tokenHoldersMap.set(account, balanceOf(account));
        }
        emit ExcludeFromDividends(account, value);
    }

    function updateClaimWait(uint256 newClaimWait) external onlyOwner {
        require(
            newClaimWait >= 3600 && newClaimWait <= 86400,
            "TETHER_Dividend_Tracker: claimWait must be updated to between 1 and 24 hours"
        );
        require(
            newClaimWait != claimWait,
            "TETHER_Dividend_Tracker: Cannot update claimWait to same value"
        );
        emit ClaimWaitUpdated(newClaimWait, claimWait);
        claimWait = newClaimWait;
    }

    function getLastProcessedIndex() external view returns (uint256) {
        return lastProcessedIndex;
    }

    function getNumberOfTokenHolders() external view returns (uint256) {
        return tokenHoldersMap.keys.length;
    }

    function getCurrentRewardToken() external view returns (string memory) {
        return IERC20Metadata(rewardToken).name();
    }

    function getAccount(address _account)
        public
        view
        returns (
            address account,
            int256 index,
            int256 iterationsUntilProcessed,
            uint256 withdrawableDividends,
            uint256 totalDividends,
            uint256 lastClaimTime,
            uint256 nextClaimTime,
            uint256 secondsUntilAutoClaimAvailable
        )
    {
        account = _account;

        index = tokenHoldersMap.getIndexOfKey(account);

        iterationsUntilProcessed = -1;

        if (index >= 0) {
            if (uint256(index) > lastProcessedIndex) {
                iterationsUntilProcessed = index.sub(int256(lastProcessedIndex));
            } else {
                uint256 processesUntilEndOfArray = tokenHoldersMap.keys.length >
                    lastProcessedIndex
                    ? tokenHoldersMap.keys.length.sub(lastProcessedIndex)
                    : 0;

                iterationsUntilProcessed = index + (int256(processesUntilEndOfArray));
            }
        }

        withdrawableDividends = withdrawableDividendOf(account);
        totalDividends = accumulativeDividendOf(account);

        lastClaimTime = lastClaimTimes[account];

        nextClaimTime = lastClaimTime > 0 ? lastClaimTime + (claimWait) : 0;

        secondsUntilAutoClaimAvailable = nextClaimTime > block.timestamp
            ? nextClaimTime.sub(block.timestamp)
            : 0;
    }

    function getAccountAtIndex(uint256 index)
        public
        view
        returns (
            address,
            int256,
            int256,
            uint256,
            uint256,
            uint256,
            uint256,
            uint256
        )
    {
        if (index >= tokenHoldersMap.size()) {
            return (0x0000000000000000000000000000000000000000, -1, -1, 0, 0, 0, 0, 0);
        }

        address account = tokenHoldersMap.getKeyAtIndex(index);

        return getAccount(account);
    }

    function canAutoClaim(uint256 lastClaimTime) private view returns (bool) {
        if (lastClaimTime > block.timestamp) {
            return false;
        }

        return block.timestamp.sub(lastClaimTime) >= claimWait;
    }

    function setBalance(address account, uint256 newBalance) public onlyOwner {
        if (excludedFromDividends[account]) {
            return;
        }

        if (newBalance >= minimumTokenBalanceForDividends) {
            _setBalance(account, newBalance);
            tokenHoldersMap.set(account, newBalance);
        } else {
            _setBalance(account, 0);
            tokenHoldersMap.remove(account);
        }

        processAccount(payable(account), true);
    }

    function process(uint256 gas)
        public
        returns (
            uint256,
            uint256,
            uint256
        )
    {
        uint256 numberOfTokenHolders = tokenHoldersMap.keys.length;

        if (numberOfTokenHolders == 0) {
            return (0, 0, lastProcessedIndex);
        }

        uint256 _lastProcessedIndex = lastProcessedIndex;

        uint256 gasUsed = 0;

        uint256 gasLeft = gasleft();

        uint256 iterations = 0;
        uint256 claims = 0;

        while (gasUsed < gas && iterations < numberOfTokenHolders) {
            _lastProcessedIndex++;

            if (_lastProcessedIndex >= tokenHoldersMap.keys.length) {
                _lastProcessedIndex = 0;
            }

            address account = tokenHoldersMap.keys[_lastProcessedIndex];

            if (canAutoClaim(lastClaimTimes[account])) {
                if (processAccount(payable(account), true)) {
                    claims++;
                }
            }

            iterations++;

            uint256 newGasLeft = gasleft();

            if (gasLeft > newGasLeft) {
                gasUsed = gasUsed + (gasLeft.sub(newGasLeft));
            }

            gasLeft = newGasLeft;
        }

        lastProcessedIndex = _lastProcessedIndex;

        return (iterations, claims, lastProcessedIndex);
    }

    function processAccount(address payable account, bool automatic)
        public
        onlyOwner
        returns (bool)
    {
        uint256 amount = _withdrawDividendOfUser(account);

        if (amount > 0) {
            lastClaimTimes[account] = block.timestamp;
            emit Claim(account, amount, automatic);
            return true;
        }

        return false;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"bool","name":"automatic","type":"bool"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"newValue","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"oldValue","type":"uint256"}],"name":"ClaimWaitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"weiAmount","type":"uint256"}],"name":"DividendWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"weiAmount","type":"uint256"}],"name":"DividendsDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"value","type":"bool"}],"name":"ExcludeFromDividends","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"accumulativeDividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimWait","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributeDividends","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"dividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"excludeFromDividends","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"excludedFromDividends","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAccount","outputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"int256","name":"index","type":"int256"},{"internalType":"int256","name":"iterationsUntilProcessed","type":"int256"},{"internalType":"uint256","name":"withdrawableDividends","type":"uint256"},{"internalType":"uint256","name":"totalDividends","type":"uint256"},{"internalType":"uint256","name":"lastClaimTime","type":"uint256"},{"internalType":"uint256","name":"nextClaimTime","type":"uint256"},{"internalType":"uint256","name":"secondsUntilAutoClaimAvailable","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getAccountAtIndex","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentRewardToken","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastProcessedIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumberOfTokenHolders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastClaimTimes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastProcessedIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumTokenBalanceForDividends","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"gas","type":"uint256"}],"name":"process","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"},{"internalType":"bool","name":"automatic","type":"bool"}],"name":"processAccount","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"setBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMinBalanceForDividends","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newToken","type":"address"}],"name":"setRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDividendsDistributed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newClaimWait","type":"uint256"}],"name":"updateClaimWait","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"withdrawableDividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"withdrawnDividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040523480156200001157600080fd5b506040518060400160405280601681526020017f5445544845525f4469766964656e5f547261636b6572000000000000000000008152506040518060400160405280601781526020017f5445544845525f4469766964656e645f547261636b65720000000000000000008152508181816003908162000091919062000229565b506004620000a0828262000229565b5050506000620000b56200018060201b60201c565b600580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35050600680546001600160a01b0319908116737a250d5630b4cf539739df2c5dacb4c659f2488d179091556007805490911673dac17f958d2ee523a2206206994597c13d831ec717905550610e106013556200015c600990565b6200016990600a6200040a565b62000177906103e862000422565b6014556200043c565b3390565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620001af57607f821691505b602082108103620001d057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200022457600081815260208120601f850160051c81016020861015620001ff5750805b601f850160051c820191505b8181101562000220578281556001016200020b565b5050505b505050565b81516001600160401b0381111562000245576200024562000184565b6200025d816200025684546200019a565b84620001d6565b602080601f8311600181146200029557600084156200027c5750858301515b600019600386901b1c1916600185901b17855562000220565b600085815260208120601f198616915b82811015620002c657888601518255948401946001909101908401620002a5565b5085821015620002e55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600181815b808511156200034c578160001904821115620003305762000330620002f5565b808516156200033e57918102915b93841c939080029062000310565b509250929050565b600082620003655750600162000404565b81620003745750600062000404565b81600181146200038d57600281146200039857620003b8565b600191505062000404565b60ff841115620003ac57620003ac620002f5565b50506001821b62000404565b5060208310610133831016604e8410600b8410161715620003dd575081810a62000404565b620003e983836200030b565b8060001904821115620004005762000400620002f5565b0290505b92915050565b60006200041b60ff84168362000354565b9392505050565b8082028115828204841417620004045762000404620002f5565b6127e9806200044c6000396000f3fe6080604052600436106102345760003560e01c80638aee81271161012e578063be10b614116100ab578063f2fde38b1161006f578063f2fde38b146106ed578063f7c618c11461070d578063f887ea401461072d578063fbcbc0f11461074d578063ffb2c4791461076d57600080fd5b8063be10b6141461063c578063dd62ed3e14610652578063e30443bc14610698578063e7841ec0146106b8578063e98030c7146106cd57600080fd5b8063a457c2d7116100f2578063a457c2d714610586578063a8b9d240146105a6578063a9059cbb146105c6578063aafd847a146105e6578063bc4c4b371461061c57600080fd5b80638aee8127146104df5780638da5cb5b146104ff57806391b89fba1461053157806395d89b41146105515780639d7ceafb1461056657600080fd5b80633009a609116101bc5780636f2789ec116101805780636f2789ec1461045357806370a0823114610469578063715018a61461049f578063854c84dc146104b457806385a6b3ae146104c957600080fd5b80633009a6091461036c578063313ce56714610382578063395093511461039e5780634e7b827f146103be5780635183d6fd146103ee57600080fd5b806309bbedde1161020357806309bbedde146102cb57806318160ddd146102ea578063226cfa3d146102ff57806323b872dd1461032c57806327ce01471461034c57600080fd5b806303c83302146102485780630483f7a01461025057806306fdde0314610270578063095ea7b31461029b57600080fd5b36610243576102416107a8565b005b600080fd5b6102416107a8565b34801561025c57600080fd5b5061024161026b36600461216d565b61083b565b34801561027c57600080fd5b50610285610a5d565b60405161029291906121c6565b60405180910390f35b3480156102a757600080fd5b506102bb6102b63660046121f9565b610aef565b6040519015158152602001610292565b3480156102d757600080fd5b50600c545b604051908152602001610292565b3480156102f657600080fd5b506002546102dc565b34801561030b57600080fd5b506102dc61031a366004612225565b60126020526000908152604090205481565b34801561033857600080fd5b506102bb610347366004612242565b610b06565b34801561035857600080fd5b506102dc610367366004612225565b610b6f565b34801561037857600080fd5b506102dc60105481565b34801561038e57600080fd5b5060405160098152602001610292565b3480156103aa57600080fd5b506102bb6103b93660046121f9565b610bcb565b3480156103ca57600080fd5b506102bb6103d9366004612225565b60116020526000908152604090205460ff1681565b3480156103fa57600080fd5b5061040e610409366004612283565b610c01565b604080516001600160a01b0390991689526020890197909752958701949094526060860192909252608085015260a084015260c083015260e082015261010001610292565b34801561045f57600080fd5b506102dc60135481565b34801561047557600080fd5b506102dc610484366004612225565b6001600160a01b031660009081526020819052604090205490565b3480156104ab57600080fd5b50610241610d55565b3480156104c057600080fd5b50610285610dc9565b3480156104d557600080fd5b506102dc600b5481565b3480156104eb57600080fd5b506102416104fa366004612225565b610e40565b34801561050b57600080fd5b506005546001600160a01b03165b6040516001600160a01b039091168152602001610292565b34801561053d57600080fd5b506102dc61054c366004612225565b610e8c565b34801561055d57600080fd5b50610285610e97565b34801561057257600080fd5b50610241610581366004612283565b610ea6565b34801561059257600080fd5b506102bb6105a13660046121f9565b610eec565b3480156105b257600080fd5b506102dc6105c1366004612225565b610f3b565b3480156105d257600080fd5b506102bb6105e13660046121f9565b610f67565b3480156105f257600080fd5b506102dc610601366004612225565b6001600160a01b03166000908152600a602052604090205490565b34801561062857600080fd5b506102bb61063736600461216d565b610f74565b34801561064857600080fd5b506102dc60145481565b34801561065e57600080fd5b506102dc61066d36600461229c565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b3480156106a457600080fd5b506102416106b33660046121f9565b611022565b3480156106c457600080fd5b506010546102dc565b3480156106d957600080fd5b506102416106e8366004612283565b61118c565b3480156106f957600080fd5b50610241610708366004612225565b6112fc565b34801561071957600080fd5b50600754610519906001600160a01b031681565b34801561073957600080fd5b50600654610519906001600160a01b031681565b34801561075957600080fd5b5061040e610768366004612225565b6113e7565b34801561077957600080fd5b5061078d610788366004612283565b61154f565b60408051938452602084019290925290820152606001610292565b60006107b360025490565b116107bd57600080fd5b3415610839576107f06107cf60025490565b6107dd34600160801b61166c565b6107e791906122eb565b600854906116f5565b60085560405134815233907fa493a9229478c3fcd73f66d2cdeb7f94fd0f341da924d1054236d784541165119060200160405180910390a2600b5461083590346116f5565b600b555b565b6005546001600160a01b0316331461086e5760405162461bcd60e51b81526004016108659061230d565b60405180910390fd5b6001600160a01b03821660009081526011602052604090205481151560ff90911615150361089b57600080fd5b6001600160a01b0382166000908152601160205260409020805460ff191682151590811790915560010361094b576108d4826000611754565b60405163131836e760e21b8152600c60048201526001600160a01b0383166024820152732da33fed9ea279150eb179a70df4c6b8f2e27ebf90634c60db9c9060440160006040518083038186803b15801561092e57600080fd5b505af4158015610942573d6000803e3d6000fd5b50505050610a14565b6109738261096e846001600160a01b031660009081526020819052604090205490565b611754565b732da33fed9ea279150eb179a70df4c6b8f2e27ebf63bc2b405c600c846109af816001600160a01b031660009081526020819052604090205490565b6040516001600160e01b031960e086901b16815260048101939093526001600160a01b039091166024830152604482015260640160006040518083038186803b1580156109fb57600080fd5b505af4158015610a0f573d6000803e3d6000fd5b505050505b816001600160a01b03167fa3c7c11b2e12c4144b09a7813f3393ba646392788638998c97be8da908cf04be82604051610a51911515815260200190565b60405180910390a25050565b606060038054610a6c90612342565b80601f0160208091040260200160405190810160405280929190818152602001828054610a9890612342565b8015610ae55780601f10610aba57610100808354040283529160200191610ae5565b820191906000526020600020905b815481529060010190602001808311610ac857829003601f168201915b5050505050905090565b6000610afc3384846117b9565b5060015b92915050565b6000610b138484846118dd565b610b658433610b6085604051806060016040528060288152602001612767602891396001600160a01b038a166000908152600160209081526040808320338452909152902054919061193b565b6117b9565b5060019392505050565b6001600160a01b03811660009081526009602090815260408083205491839052822054600854600160801b92610bc192610bbc92610bb691610bb1919061166c565b611975565b90611985565b6119c3565b610b0091906122eb565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610afc918590610b6090866116f5565b600080600080600080600080600c732da33fed9ea279150eb179a70df4c6b8f2e27ebf63deb3d89690916040518263ffffffff1660e01b8152600401610c4991815260200190565b602060405180830381865af4158015610c66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8a919061237c565b8910610caf575060009650600019955085945086935083925082915081905080610d4a565b6040516368d54f3f60e11b8152600c6004820152602481018a9052600090732da33fed9ea279150eb179a70df4c6b8f2e27ebf9063d1aa9e7e90604401602060405180830381865af4158015610d09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2d9190612395565b9050610d38816113e7565b98509850985098509850985098509850505b919395975091939597565b6005546001600160a01b03163314610d7f5760405162461bcd60e51b81526004016108659061230d565b6005546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580546001600160a01b0319169055565b600754604080516306fdde0360e01b815290516060926001600160a01b0316916306fdde039160048083019260009291908290030181865afa158015610e13573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e3b91908101906123f9565b905090565b6005546001600160a01b03163314610e6a5760405162461bcd60e51b81526004016108659061230d565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b6000610b0082610f3b565b606060048054610a6c90612342565b6005546001600160a01b03163314610ed05760405162461bcd60e51b81526004016108659061230d565b610edc6009600a612571565b610ee69082612580565b60145550565b6000610afc3384610b608560405180606001604052806025815260200161278f602591393360009081526001602090815260408083206001600160a01b038d168452909152902054919061193b565b6001600160a01b0381166000908152600a6020526040812054610b0090610f6184610b6f565b906119d6565b6000610afc3384846118dd565b6005546000906001600160a01b03163314610fa15760405162461bcd60e51b81526004016108659061230d565b6000610fac84611a18565b90508015611018576001600160a01b038416600081815260126020526040908190204290555184151591907fa2c38e2d2fb7e3e1912d937fd1ca11ed6d51864dee4cfa7a7bf02becd7acf092906110069085815260200190565b60405180910390a36001915050610b00565b5060009392505050565b6005546001600160a01b0316331461104c5760405162461bcd60e51b81526004016108659061230d565b6001600160a01b03821660009081526011602052604090205460ff166111885760145481106110fd5761107f8282611754565b604051632f0ad01760e21b8152600c60048201526001600160a01b038316602482015260448101829052732da33fed9ea279150eb179a70df4c6b8f2e27ebf9063bc2b405c9060640160006040518083038186803b1580156110e057600080fd5b505af41580156110f4573d6000803e3d6000fd5b5050505061117b565b611108826000611754565b60405163131836e760e21b8152600c60048201526001600160a01b0383166024820152732da33fed9ea279150eb179a70df4c6b8f2e27ebf90634c60db9c9060440160006040518083038186803b15801561116257600080fd5b505af4158015611176573d6000803e3d6000fd5b505050505b611186826001610f74565b505b5050565b6005546001600160a01b031633146111b65760405162461bcd60e51b81526004016108659061230d565b610e1081101580156111cb5750620151808111155b6112525760405162461bcd60e51b815260206004820152604c60248201527f5445544845525f4469766964656e645f547261636b65723a20636c61696d576160448201527f6974206d757374206265207570646174656420746f206265747765656e20312060648201526b616e6420323420686f75727360a01b608482015260a401610865565b60135481036112c95760405162461bcd60e51b815260206004820152603e60248201527f5445544845525f4469766964656e645f547261636b65723a2043616e6e6f742060448201527f75706461746520636c61696d5761697420746f2073616d652076616c756500006064820152608401610865565b60135460405182907f474ea64804364a1e29a4487ddb63c3342a2dd826ccd8acf48825e680a0e6f20f90600090a3601355565b6005546001600160a01b031633146113265760405162461bcd60e51b81526004016108659061230d565b6001600160a01b03811661138b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610865565b6005546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b6040516317e142d160e01b8152600c60048201526001600160a01b03821660248201528190600090819081908190819081908190732da33fed9ea279150eb179a70df4c6b8f2e27ebf906317e142d190604401602060405180830381865af4158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b919061237c565b96506000199550600087126114dd576010548711156114a9576010546114a2908890611cae565b95506114dd565b601054600c54600091106114be5760006114cd565b601054600c546114cd916119d6565b90506114d98189612597565b9650505b6114e688610f3b565b94506114f188610b6f565b6001600160a01b03891660009081526012602052604090205490945092508261151b576000611528565b60135461152890846125bf565b9150428211611538576000611542565b61154282426119d6565b9050919395975091939597565b600c546000908190819080820361157157505060105460009250829150611665565b6010546000805a90506000805b898410801561158c57508582105b15611654578461159b816125d2565b600c54909650861090506115ae57600094505b6000600c60000186815481106115c6576115c66125eb565b60009182526020808320909101546001600160a01b031680835260129091526040909120549091506115f790611ceb565b1561161a57611607816001610f74565b1561161a5781611616816125d2565b9250505b82611624816125d2565b93505060005a90508085111561164b5761163e85826119d6565b61164890876125bf565b95505b935061157e9050565b601085905590975095509193505050505b9193909250565b60008260000361167e57506000610b00565b600061168a8385612580565b90508261169785836122eb565b146116ee5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610865565b9392505050565b60008061170283856125bf565b9050838110156116ee5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610865565b6001600160a01b0382166000908152602081905260409020548082111561179357600061178183836119d6565b905061178d8482611d12565b50611186565b808210156111865760006117a782846119d6565b90506117b38482611d76565b50505050565b6001600160a01b03831661181b5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610865565b6001600160a01b03821661187c5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610865565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60405162461bcd60e51b815260206004820152602d60248201527f5445544845525f4469766964656e645f547261636b65723a204e6f207472616e60448201526c1cd9995c9cc8185b1b1bddd959609a1b6064820152608401610865565b6000818484111561195f5760405162461bcd60e51b815260040161086591906121c6565b50600061196c8486612601565b95945050505050565b60008181811215610b0057600080fd5b6000806119928385612597565b9050600083121580156119a55750838112155b806119ba57506000831280156119ba57508381125b6116ee57600080fd5b6000808212156119d257600080fd5b5090565b60006116ee83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061193b565b600080611a2483610f3b565b90508015611ca5576001600160a01b0383166000908152600a6020526040902054611a4f90826116f5565b6001600160a01b0384166000818152600a6020526040908190209290925590517fee503bee2bb6a87e57bc57db795f98137327401a0e7b7ce42e37926cc1a9ca4d90611a9e9084815260200190565b60405180910390a2600660009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611af9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b1d9190612395565b6007546001600160a01b03908116911614611bf6576000611b3e8483611dba565b905080611bf0576000846001600160a01b031683610bb890604051600060405180830381858888f193505050503d8060008114611b97576040519150601f19603f3d011682016040523d82523d6000602084013e611b9c565b606091505b5050905080611bee576001600160a01b0385166000908152600a6020526040902054611bc890846119d6565b6001600160a01b039095166000908152600a602052604081209590955550929392505050565b505b50610b00565b6000836001600160a01b031682610bb890604051600060405180830381858888f193505050503d8060008114611c48576040519150601f19603f3d011682016040523d82523d6000602084013e611c4d565b606091505b5050905080611c9e576001600160a01b0384166000908152600a6020526040902054611c7990836119d6565b6001600160a01b039094166000908152600a6020526040812094909455509192915050565b5092915050565b50600092915050565b600080611cbb8385612614565b905060008312158015611cce5750838113155b806119ba57506000831280156119ba57508381136116ee57600080fd5b600042821115611cfd57506000919050565b601354611d0a42846119d6565b101592915050565b611d1c8282611f37565b611d56611d37610bb18360085461166c90919063ffffffff16565b6001600160a01b03841660009081526009602052604090205490611cae565b6001600160a01b0390921660009081526009602052604090209190915550565b611d808282612030565b611d56611d9b610bb18360085461166c90919063ffffffff16565b6001600160a01b03841660009081526009602052604090205490611985565b604080516002808252606082018352600092839291906020830190803683375050600654604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c4648925060048083019260209291908290030181865afa158015611e28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4c9190612395565b81600081518110611e5f57611e5f6125eb565b6001600160a01b039283166020918202929092010152600754825191169082906001908110611e9057611e906125eb565b6001600160a01b03928316602091820292909201015260065416637ff36ab58460008488611ebf4260026125bf565b6040518663ffffffff1660e01b8152600401611ede9493929190612634565b60006040518083038185885af193505050508015611f1e57506040513d6000823e601f3d908101601f19168201604052611f1b919081019061269e565b60015b611f2c576000915050610b00565b506001915050610b00565b6001600160a01b038216611f9b5760405162461bcd60e51b815260206004820152602560248201527f45524332303a206e657720746f6b656e7320746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610865565b611fa760008383611186565b600254611fb490826116f5565b6002556001600160a01b038216600090815260208190526040902054611fda90826116f5565b6001600160a01b038316600081815260208181526040808320949094559251848152919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91015b60405180910390a35050565b6001600160a01b0382166120905760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610865565b61209c82600083611186565b6120d981604051806060016040528060228152602001612745602291396001600160a01b038516600090815260208190526040902054919061193b565b6001600160a01b0383166000908152602081905260409020556002546120ff90826119d6565b6002556040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612024565b6001600160a01b038116811461215557600080fd5b50565b8035801515811461216857600080fd5b919050565b6000806040838503121561218057600080fd5b823561218b81612140565b915061219960208401612158565b90509250929050565b60005b838110156121bd5781810151838201526020016121a5565b50506000910152565b60208152600082518060208401526121e58160408501602087016121a2565b601f01601f19169190910160400192915050565b6000806040838503121561220c57600080fd5b823561221781612140565b946020939093013593505050565b60006020828403121561223757600080fd5b81356116ee81612140565b60008060006060848603121561225757600080fd5b833561226281612140565b9250602084013561227281612140565b929592945050506040919091013590565b60006020828403121561229557600080fd5b5035919050565b600080604083850312156122af57600080fd5b82356122ba81612140565b915060208301356122ca81612140565b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b60008261230857634e487b7160e01b600052601260045260246000fd5b500490565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600181811c9082168061235657607f821691505b60208210810361237657634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561238e57600080fd5b5051919050565b6000602082840312156123a757600080fd5b81516116ee81612140565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156123f1576123f16123b2565b604052919050565b60006020828403121561240b57600080fd5b815167ffffffffffffffff8082111561242357600080fd5b818401915084601f83011261243757600080fd5b815181811115612449576124496123b2565b61245c601f8201601f19166020016123c8565b915080825285602082850101111561247357600080fd5b6124848160208401602086016121a2565b50949350505050565b600181815b808511156124c85781600019048211156124ae576124ae6122d5565b808516156124bb57918102915b93841c9390800290612492565b509250929050565b6000826124df57506001610b00565b816124ec57506000610b00565b8160018114612502576002811461250c57612528565b6001915050610b00565b60ff84111561251d5761251d6122d5565b50506001821b610b00565b5060208310610133831016604e8410600b841016171561254b575081810a610b00565b612555838361248d565b8060001904821115612569576125696122d5565b029392505050565b60006116ee60ff8416836124d0565b8082028115828204841417610b0057610b006122d5565b80820182811260008312801582168215821617156125b7576125b76122d5565b505092915050565b80820180821115610b0057610b006122d5565b6000600182016125e4576125e46122d5565b5060010190565b634e487b7160e01b600052603260045260246000fd5b81810381811115610b0057610b006122d5565b8181036000831280158383131683831282161715611c9e57611c9e6122d5565b600060808201868352602060808185015281875180845260a086019150828901935060005b8181101561267e5784516001600160a01b031683529383019391830191600101612659565b50506001600160a01b039690961660408501525050506060015292915050565b600060208083850312156126b157600080fd5b825167ffffffffffffffff808211156126c957600080fd5b818501915085601f8301126126dd57600080fd5b8151818111156126ef576126ef6123b2565b8060051b91506127008483016123c8565b818152918301840191848101908884111561271a57600080fd5b938501935b838510156127385784518252938501939085019061271f565b9897505050505050505056fe45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c6774a4d7ae731b7105c89babd0ef1d5ff11e3503a14ea58a588acc1ad200d3764736f6c63430008130033

Deployed Bytecode

0x6080604052600436106102345760003560e01c80638aee81271161012e578063be10b614116100ab578063f2fde38b1161006f578063f2fde38b146106ed578063f7c618c11461070d578063f887ea401461072d578063fbcbc0f11461074d578063ffb2c4791461076d57600080fd5b8063be10b6141461063c578063dd62ed3e14610652578063e30443bc14610698578063e7841ec0146106b8578063e98030c7146106cd57600080fd5b8063a457c2d7116100f2578063a457c2d714610586578063a8b9d240146105a6578063a9059cbb146105c6578063aafd847a146105e6578063bc4c4b371461061c57600080fd5b80638aee8127146104df5780638da5cb5b146104ff57806391b89fba1461053157806395d89b41146105515780639d7ceafb1461056657600080fd5b80633009a609116101bc5780636f2789ec116101805780636f2789ec1461045357806370a0823114610469578063715018a61461049f578063854c84dc146104b457806385a6b3ae146104c957600080fd5b80633009a6091461036c578063313ce56714610382578063395093511461039e5780634e7b827f146103be5780635183d6fd146103ee57600080fd5b806309bbedde1161020357806309bbedde146102cb57806318160ddd146102ea578063226cfa3d146102ff57806323b872dd1461032c57806327ce01471461034c57600080fd5b806303c83302146102485780630483f7a01461025057806306fdde0314610270578063095ea7b31461029b57600080fd5b36610243576102416107a8565b005b600080fd5b6102416107a8565b34801561025c57600080fd5b5061024161026b36600461216d565b61083b565b34801561027c57600080fd5b50610285610a5d565b60405161029291906121c6565b60405180910390f35b3480156102a757600080fd5b506102bb6102b63660046121f9565b610aef565b6040519015158152602001610292565b3480156102d757600080fd5b50600c545b604051908152602001610292565b3480156102f657600080fd5b506002546102dc565b34801561030b57600080fd5b506102dc61031a366004612225565b60126020526000908152604090205481565b34801561033857600080fd5b506102bb610347366004612242565b610b06565b34801561035857600080fd5b506102dc610367366004612225565b610b6f565b34801561037857600080fd5b506102dc60105481565b34801561038e57600080fd5b5060405160098152602001610292565b3480156103aa57600080fd5b506102bb6103b93660046121f9565b610bcb565b3480156103ca57600080fd5b506102bb6103d9366004612225565b60116020526000908152604090205460ff1681565b3480156103fa57600080fd5b5061040e610409366004612283565b610c01565b604080516001600160a01b0390991689526020890197909752958701949094526060860192909252608085015260a084015260c083015260e082015261010001610292565b34801561045f57600080fd5b506102dc60135481565b34801561047557600080fd5b506102dc610484366004612225565b6001600160a01b031660009081526020819052604090205490565b3480156104ab57600080fd5b50610241610d55565b3480156104c057600080fd5b50610285610dc9565b3480156104d557600080fd5b506102dc600b5481565b3480156104eb57600080fd5b506102416104fa366004612225565b610e40565b34801561050b57600080fd5b506005546001600160a01b03165b6040516001600160a01b039091168152602001610292565b34801561053d57600080fd5b506102dc61054c366004612225565b610e8c565b34801561055d57600080fd5b50610285610e97565b34801561057257600080fd5b50610241610581366004612283565b610ea6565b34801561059257600080fd5b506102bb6105a13660046121f9565b610eec565b3480156105b257600080fd5b506102dc6105c1366004612225565b610f3b565b3480156105d257600080fd5b506102bb6105e13660046121f9565b610f67565b3480156105f257600080fd5b506102dc610601366004612225565b6001600160a01b03166000908152600a602052604090205490565b34801561062857600080fd5b506102bb61063736600461216d565b610f74565b34801561064857600080fd5b506102dc60145481565b34801561065e57600080fd5b506102dc61066d36600461229c565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b3480156106a457600080fd5b506102416106b33660046121f9565b611022565b3480156106c457600080fd5b506010546102dc565b3480156106d957600080fd5b506102416106e8366004612283565b61118c565b3480156106f957600080fd5b50610241610708366004612225565b6112fc565b34801561071957600080fd5b50600754610519906001600160a01b031681565b34801561073957600080fd5b50600654610519906001600160a01b031681565b34801561075957600080fd5b5061040e610768366004612225565b6113e7565b34801561077957600080fd5b5061078d610788366004612283565b61154f565b60408051938452602084019290925290820152606001610292565b60006107b360025490565b116107bd57600080fd5b3415610839576107f06107cf60025490565b6107dd34600160801b61166c565b6107e791906122eb565b600854906116f5565b60085560405134815233907fa493a9229478c3fcd73f66d2cdeb7f94fd0f341da924d1054236d784541165119060200160405180910390a2600b5461083590346116f5565b600b555b565b6005546001600160a01b0316331461086e5760405162461bcd60e51b81526004016108659061230d565b60405180910390fd5b6001600160a01b03821660009081526011602052604090205481151560ff90911615150361089b57600080fd5b6001600160a01b0382166000908152601160205260409020805460ff191682151590811790915560010361094b576108d4826000611754565b60405163131836e760e21b8152600c60048201526001600160a01b0383166024820152732da33fed9ea279150eb179a70df4c6b8f2e27ebf90634c60db9c9060440160006040518083038186803b15801561092e57600080fd5b505af4158015610942573d6000803e3d6000fd5b50505050610a14565b6109738261096e846001600160a01b031660009081526020819052604090205490565b611754565b732da33fed9ea279150eb179a70df4c6b8f2e27ebf63bc2b405c600c846109af816001600160a01b031660009081526020819052604090205490565b6040516001600160e01b031960e086901b16815260048101939093526001600160a01b039091166024830152604482015260640160006040518083038186803b1580156109fb57600080fd5b505af4158015610a0f573d6000803e3d6000fd5b505050505b816001600160a01b03167fa3c7c11b2e12c4144b09a7813f3393ba646392788638998c97be8da908cf04be82604051610a51911515815260200190565b60405180910390a25050565b606060038054610a6c90612342565b80601f0160208091040260200160405190810160405280929190818152602001828054610a9890612342565b8015610ae55780601f10610aba57610100808354040283529160200191610ae5565b820191906000526020600020905b815481529060010190602001808311610ac857829003601f168201915b5050505050905090565b6000610afc3384846117b9565b5060015b92915050565b6000610b138484846118dd565b610b658433610b6085604051806060016040528060288152602001612767602891396001600160a01b038a166000908152600160209081526040808320338452909152902054919061193b565b6117b9565b5060019392505050565b6001600160a01b03811660009081526009602090815260408083205491839052822054600854600160801b92610bc192610bbc92610bb691610bb1919061166c565b611975565b90611985565b6119c3565b610b0091906122eb565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610afc918590610b6090866116f5565b600080600080600080600080600c732da33fed9ea279150eb179a70df4c6b8f2e27ebf63deb3d89690916040518263ffffffff1660e01b8152600401610c4991815260200190565b602060405180830381865af4158015610c66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8a919061237c565b8910610caf575060009650600019955085945086935083925082915081905080610d4a565b6040516368d54f3f60e11b8152600c6004820152602481018a9052600090732da33fed9ea279150eb179a70df4c6b8f2e27ebf9063d1aa9e7e90604401602060405180830381865af4158015610d09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2d9190612395565b9050610d38816113e7565b98509850985098509850985098509850505b919395975091939597565b6005546001600160a01b03163314610d7f5760405162461bcd60e51b81526004016108659061230d565b6005546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580546001600160a01b0319169055565b600754604080516306fdde0360e01b815290516060926001600160a01b0316916306fdde039160048083019260009291908290030181865afa158015610e13573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e3b91908101906123f9565b905090565b6005546001600160a01b03163314610e6a5760405162461bcd60e51b81526004016108659061230d565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b6000610b0082610f3b565b606060048054610a6c90612342565b6005546001600160a01b03163314610ed05760405162461bcd60e51b81526004016108659061230d565b610edc6009600a612571565b610ee69082612580565b60145550565b6000610afc3384610b608560405180606001604052806025815260200161278f602591393360009081526001602090815260408083206001600160a01b038d168452909152902054919061193b565b6001600160a01b0381166000908152600a6020526040812054610b0090610f6184610b6f565b906119d6565b6000610afc3384846118dd565b6005546000906001600160a01b03163314610fa15760405162461bcd60e51b81526004016108659061230d565b6000610fac84611a18565b90508015611018576001600160a01b038416600081815260126020526040908190204290555184151591907fa2c38e2d2fb7e3e1912d937fd1ca11ed6d51864dee4cfa7a7bf02becd7acf092906110069085815260200190565b60405180910390a36001915050610b00565b5060009392505050565b6005546001600160a01b0316331461104c5760405162461bcd60e51b81526004016108659061230d565b6001600160a01b03821660009081526011602052604090205460ff166111885760145481106110fd5761107f8282611754565b604051632f0ad01760e21b8152600c60048201526001600160a01b038316602482015260448101829052732da33fed9ea279150eb179a70df4c6b8f2e27ebf9063bc2b405c9060640160006040518083038186803b1580156110e057600080fd5b505af41580156110f4573d6000803e3d6000fd5b5050505061117b565b611108826000611754565b60405163131836e760e21b8152600c60048201526001600160a01b0383166024820152732da33fed9ea279150eb179a70df4c6b8f2e27ebf90634c60db9c9060440160006040518083038186803b15801561116257600080fd5b505af4158015611176573d6000803e3d6000fd5b505050505b611186826001610f74565b505b5050565b6005546001600160a01b031633146111b65760405162461bcd60e51b81526004016108659061230d565b610e1081101580156111cb5750620151808111155b6112525760405162461bcd60e51b815260206004820152604c60248201527f5445544845525f4469766964656e645f547261636b65723a20636c61696d576160448201527f6974206d757374206265207570646174656420746f206265747765656e20312060648201526b616e6420323420686f75727360a01b608482015260a401610865565b60135481036112c95760405162461bcd60e51b815260206004820152603e60248201527f5445544845525f4469766964656e645f547261636b65723a2043616e6e6f742060448201527f75706461746520636c61696d5761697420746f2073616d652076616c756500006064820152608401610865565b60135460405182907f474ea64804364a1e29a4487ddb63c3342a2dd826ccd8acf48825e680a0e6f20f90600090a3601355565b6005546001600160a01b031633146113265760405162461bcd60e51b81526004016108659061230d565b6001600160a01b03811661138b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610865565b6005546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b6040516317e142d160e01b8152600c60048201526001600160a01b03821660248201528190600090819081908190819081908190732da33fed9ea279150eb179a70df4c6b8f2e27ebf906317e142d190604401602060405180830381865af4158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b919061237c565b96506000199550600087126114dd576010548711156114a9576010546114a2908890611cae565b95506114dd565b601054600c54600091106114be5760006114cd565b601054600c546114cd916119d6565b90506114d98189612597565b9650505b6114e688610f3b565b94506114f188610b6f565b6001600160a01b03891660009081526012602052604090205490945092508261151b576000611528565b60135461152890846125bf565b9150428211611538576000611542565b61154282426119d6565b9050919395975091939597565b600c546000908190819080820361157157505060105460009250829150611665565b6010546000805a90506000805b898410801561158c57508582105b15611654578461159b816125d2565b600c54909650861090506115ae57600094505b6000600c60000186815481106115c6576115c66125eb565b60009182526020808320909101546001600160a01b031680835260129091526040909120549091506115f790611ceb565b1561161a57611607816001610f74565b1561161a5781611616816125d2565b9250505b82611624816125d2565b93505060005a90508085111561164b5761163e85826119d6565b61164890876125bf565b95505b935061157e9050565b601085905590975095509193505050505b9193909250565b60008260000361167e57506000610b00565b600061168a8385612580565b90508261169785836122eb565b146116ee5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610865565b9392505050565b60008061170283856125bf565b9050838110156116ee5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610865565b6001600160a01b0382166000908152602081905260409020548082111561179357600061178183836119d6565b905061178d8482611d12565b50611186565b808210156111865760006117a782846119d6565b90506117b38482611d76565b50505050565b6001600160a01b03831661181b5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610865565b6001600160a01b03821661187c5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610865565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60405162461bcd60e51b815260206004820152602d60248201527f5445544845525f4469766964656e645f547261636b65723a204e6f207472616e60448201526c1cd9995c9cc8185b1b1bddd959609a1b6064820152608401610865565b6000818484111561195f5760405162461bcd60e51b815260040161086591906121c6565b50600061196c8486612601565b95945050505050565b60008181811215610b0057600080fd5b6000806119928385612597565b9050600083121580156119a55750838112155b806119ba57506000831280156119ba57508381125b6116ee57600080fd5b6000808212156119d257600080fd5b5090565b60006116ee83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061193b565b600080611a2483610f3b565b90508015611ca5576001600160a01b0383166000908152600a6020526040902054611a4f90826116f5565b6001600160a01b0384166000818152600a6020526040908190209290925590517fee503bee2bb6a87e57bc57db795f98137327401a0e7b7ce42e37926cc1a9ca4d90611a9e9084815260200190565b60405180910390a2600660009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611af9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b1d9190612395565b6007546001600160a01b03908116911614611bf6576000611b3e8483611dba565b905080611bf0576000846001600160a01b031683610bb890604051600060405180830381858888f193505050503d8060008114611b97576040519150601f19603f3d011682016040523d82523d6000602084013e611b9c565b606091505b5050905080611bee576001600160a01b0385166000908152600a6020526040902054611bc890846119d6565b6001600160a01b039095166000908152600a602052604081209590955550929392505050565b505b50610b00565b6000836001600160a01b031682610bb890604051600060405180830381858888f193505050503d8060008114611c48576040519150601f19603f3d011682016040523d82523d6000602084013e611c4d565b606091505b5050905080611c9e576001600160a01b0384166000908152600a6020526040902054611c7990836119d6565b6001600160a01b039094166000908152600a6020526040812094909455509192915050565b5092915050565b50600092915050565b600080611cbb8385612614565b905060008312158015611cce5750838113155b806119ba57506000831280156119ba57508381136116ee57600080fd5b600042821115611cfd57506000919050565b601354611d0a42846119d6565b101592915050565b611d1c8282611f37565b611d56611d37610bb18360085461166c90919063ffffffff16565b6001600160a01b03841660009081526009602052604090205490611cae565b6001600160a01b0390921660009081526009602052604090209190915550565b611d808282612030565b611d56611d9b610bb18360085461166c90919063ffffffff16565b6001600160a01b03841660009081526009602052604090205490611985565b604080516002808252606082018352600092839291906020830190803683375050600654604080516315ab88c960e31b815290519394506001600160a01b039091169263ad5c4648925060048083019260209291908290030181865afa158015611e28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4c9190612395565b81600081518110611e5f57611e5f6125eb565b6001600160a01b039283166020918202929092010152600754825191169082906001908110611e9057611e906125eb565b6001600160a01b03928316602091820292909201015260065416637ff36ab58460008488611ebf4260026125bf565b6040518663ffffffff1660e01b8152600401611ede9493929190612634565b60006040518083038185885af193505050508015611f1e57506040513d6000823e601f3d908101601f19168201604052611f1b919081019061269e565b60015b611f2c576000915050610b00565b506001915050610b00565b6001600160a01b038216611f9b5760405162461bcd60e51b815260206004820152602560248201527f45524332303a206e657720746f6b656e7320746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610865565b611fa760008383611186565b600254611fb490826116f5565b6002556001600160a01b038216600090815260208190526040902054611fda90826116f5565b6001600160a01b038316600081815260208181526040808320949094559251848152919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91015b60405180910390a35050565b6001600160a01b0382166120905760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610865565b61209c82600083611186565b6120d981604051806060016040528060228152602001612745602291396001600160a01b038516600090815260208190526040902054919061193b565b6001600160a01b0383166000908152602081905260409020556002546120ff90826119d6565b6002556040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612024565b6001600160a01b038116811461215557600080fd5b50565b8035801515811461216857600080fd5b919050565b6000806040838503121561218057600080fd5b823561218b81612140565b915061219960208401612158565b90509250929050565b60005b838110156121bd5781810151838201526020016121a5565b50506000910152565b60208152600082518060208401526121e58160408501602087016121a2565b601f01601f19169190910160400192915050565b6000806040838503121561220c57600080fd5b823561221781612140565b946020939093013593505050565b60006020828403121561223757600080fd5b81356116ee81612140565b60008060006060848603121561225757600080fd5b833561226281612140565b9250602084013561227281612140565b929592945050506040919091013590565b60006020828403121561229557600080fd5b5035919050565b600080604083850312156122af57600080fd5b82356122ba81612140565b915060208301356122ca81612140565b809150509250929050565b634e487b7160e01b600052601160045260246000fd5b60008261230857634e487b7160e01b600052601260045260246000fd5b500490565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600181811c9082168061235657607f821691505b60208210810361237657634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561238e57600080fd5b5051919050565b6000602082840312156123a757600080fd5b81516116ee81612140565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156123f1576123f16123b2565b604052919050565b60006020828403121561240b57600080fd5b815167ffffffffffffffff8082111561242357600080fd5b818401915084601f83011261243757600080fd5b815181811115612449576124496123b2565b61245c601f8201601f19166020016123c8565b915080825285602082850101111561247357600080fd5b6124848160208401602086016121a2565b50949350505050565b600181815b808511156124c85781600019048211156124ae576124ae6122d5565b808516156124bb57918102915b93841c9390800290612492565b509250929050565b6000826124df57506001610b00565b816124ec57506000610b00565b8160018114612502576002811461250c57612528565b6001915050610b00565b60ff84111561251d5761251d6122d5565b50506001821b610b00565b5060208310610133831016604e8410600b841016171561254b575081810a610b00565b612555838361248d565b8060001904821115612569576125696122d5565b029392505050565b60006116ee60ff8416836124d0565b8082028115828204841417610b0057610b006122d5565b80820182811260008312801582168215821617156125b7576125b76122d5565b505092915050565b80820180821115610b0057610b006122d5565b6000600182016125e4576125e46122d5565b5060010190565b634e487b7160e01b600052603260045260246000fd5b81810381811115610b0057610b006122d5565b8181036000831280158383131683831282161715611c9e57611c9e6122d5565b600060808201868352602060808185015281875180845260a086019150828901935060005b8181101561267e5784516001600160a01b031683529383019391830191600101612659565b50506001600160a01b039690961660408501525050506060015292915050565b600060208083850312156126b157600080fd5b825167ffffffffffffffff808211156126c957600080fd5b818501915085601f8301126126dd57600080fd5b8151818111156126ef576126ef6123b2565b8060051b91506127008483016123c8565b818152918301840191848101908884111561271a57600080fd5b938501935b838510156127385784518252938501939085019061271f565b9897505050505050505056fe45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c6774a4d7ae731b7105c89babd0ef1d5ff11e3503a14ea58a588acc1ad200d3764736f6c63430008130033

Libraries Used

IterableMapping : 0x2da33fed9ea279150eb179a70df4c6b8f2e27ebfUnverified

Deployed Bytecode Sourcemap

50745:7262:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26579:21;:19;:21::i;:::-;50745:7262;;;;;26617:411;;;:::i;52032:507::-;;;;;;;;;;-1:-1:-1;52032:507:0;;;;;:::i;:::-;;:::i;4586:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6752:169;;;;;;;;;;-1:-1:-1;6752:169:0;;;;;:::i;:::-;;:::i;:::-;;;1776:14:1;;1769:22;1751:41;;1739:2;1724:18;6752:169:0;1611:187:1;53168:120:0;;;;;;;;;;-1:-1:-1;53253:15:0;:27;53168:120;;;1949:25:1;;;1937:2;1922:18;53168:120:0;1803:177:1;5705:108:0;;;;;;;;;;-1:-1:-1;5793:12:0;;5705:108;;51092:49;;;;;;;;;;-1:-1:-1;51092:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;7403:355;;;;;;;;;;-1:-1:-1;7403:355:0;;;;;:::i;:::-;;:::i;30517:253::-;;;;;;;;;;-1:-1:-1;30517:253:0;;;;;:::i;:::-;;:::i;50988:33::-;;;;;;;;;;;;;;;;5548:92;;;;;;;;;;-1:-1:-1;5548:92:0;;5631:1;2840:36:1;;2828:2;2813:18;5548:92:0;2698:184:1;8167:218:0;;;;;;;;;;-1:-1:-1;8167:218:0;;;;;:::i;:::-;;:::i;51030:53::-;;;;;;;;;;-1:-1:-1;51030:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;54924:542;;;;;;;;;;-1:-1:-1;54924:542:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;3429:32:1;;;3411:51;;3493:2;3478:18;;3471:34;;;;3521:18;;;3514:34;;;;3579:2;3564:18;;3557:34;;;;3622:3;3607:19;;3600:35;3449:3;3651:19;;3644:35;3710:3;3695:19;;3688:35;3754:3;3739:19;;3732:35;3398:3;3383:19;54924:542:0;3072:701:1;51150:24:0;;;;;;;;;;;;;;;;5876:127;;;;;;;;;;-1:-1:-1;5876:127:0;;;;;:::i;:::-;-1:-1:-1;;;;;5977:18:0;5950:7;5977:18;;;;;;;;;;;;5876:127;20546:148;;;;;;;;;;;;;:::i;53296:131::-;;;;;;;;;;;;;:::i;26157:40::-;;;;;;;;;;;;;;;;28470:101;;;;;;;;;;-1:-1:-1;28470:101:0;;;;;:::i;:::-;;:::i;19904:79::-;;;;;;;;;;-1:-1:-1;19969:6:0;;-1:-1:-1;;;;;19969:6:0;19904:79;;;-1:-1:-1;;;;;3942:32:1;;;3924:51;;3912:2;3897:18;19904:79:0;3778:203:1;29191:128:0;;;;;;;;;;-1:-1:-1;29191:128:0;;;;;:::i;:::-;;:::i;4805:104::-;;;;;;;;;;;;;:::i;51878:146::-;;;;;;;;;;-1:-1:-1;51878:146:0;;;;;:::i;:::-;;:::i;8888:269::-;;;;;;;;;;-1:-1:-1;8888:269:0;;;;;:::i;:::-;;:::i;29538:172::-;;;;;;;;;;-1:-1:-1;29538:172:0;;;;;:::i;:::-;;:::i;6216:175::-;;;;;;;;;;-1:-1:-1;6216:175:0;;;;;:::i;:::-;;:::i;29931:133::-;;;;;;;;;;-1:-1:-1;29931:133:0;;;;;:::i;:::-;-1:-1:-1;;;;;30030:26:0;30005:7;30030:26;;;:18;:26;;;;;;;29931:133;57607:397;;;;;;;;;;-1:-1:-1;57607:397:0;;;;;:::i;:::-;;:::i;51181:46::-;;;;;;;;;;;;;;;;6454:151;;;;;;;;;;-1:-1:-1;6454:151:0;;;;;:::i;:::-;-1:-1:-1;;;;;6570:18:0;;;6543:7;6570:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;6454:151;55716:491;;;;;;;;;;-1:-1:-1;55716:491:0;;;;;:::i;:::-;;:::i;53051:109::-;;;;;;;;;;-1:-1:-1;53134:18:0;;53051:109;;52547:496;;;;;;;;;;-1:-1:-1;52547:496:0;;;;;:::i;:::-;;:::i;20849:244::-;;;;;;;;;;-1:-1:-1;20849:244:0;;;;;:::i;:::-;;:::i;25040:26::-;;;;;;;;;;-1:-1:-1;25040:26:0;;;;-1:-1:-1;;;;;25040:26:0;;;25014:21;;;;;;;;;;-1:-1:-1;25014:21:0;;;;-1:-1:-1;;;;;25014:21:0;;;53435:1481;;;;;;;;;;-1:-1:-1;53435:1481:0;;;;;:::i;:::-;;:::i;56215:1384::-;;;;;;;;;;-1:-1:-1;56215:1384:0;;;;;:::i;:::-;;:::i;:::-;;;;5133:25:1;;;5189:2;5174:18;;5167:34;;;;5217:18;;;5210:34;5121:2;5106:18;56215:1384:0;4931:319:1;26617:411:0;26705:1;26689:13;5793:12;;;5705:108;26689:13;:17;26681:26;;;;;;26722:9;:13;26718:303;;26776:95;26847:13;5793:12;;;5705:108;26847:13;26818:26;26819:9;-1:-1:-1;;;26818:15:0;:26::i;:::-;:42;;;;:::i;:::-;26776:25;;;:29;:95::i;:::-;26748:25;:123;26887:43;;26920:9;1949:25:1;;26908:10:0;;26887:43;;1937:2:1;1922:18;26887:43:0;;;;;;;26971:25;;:40;;27001:9;26971:29;:40::i;:::-;26943:25;:68;26718:303;26617:411::o;52032:507::-;20116:6;;-1:-1:-1;;;;;20116:6:0;210:10;20116:22;20108:67;;;;-1:-1:-1;;;20108:67:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;52129:30:0;::::1;;::::0;;;:21:::1;:30;::::0;;;;;:39;::::1;;:30;::::0;;::::1;:39;;::::0;52121:48:::1;;;::::0;::::1;;-1:-1:-1::0;;;;;52180:30:0;::::1;;::::0;;;:21:::1;:30;::::0;;;;:38;;-1:-1:-1;;52180:38:0::1;::::0;::::1;;::::0;;::::1;::::0;;;-1:-1:-1;52233:13:0;52229:251:::1;;52263:23;52275:7;52284:1;52263:11;:23::i;:::-;52301:31;::::0;-1:-1:-1;;;52301:31:0;;:15:::1;:31;::::0;::::1;6174:25:1::0;-1:-1:-1;;;;;6235:32:1;;6215:18;;;6208:60;52301:22:0::1;::::0;::::1;::::0;6147:18:1;;52301:31:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;52229:251;;;52365:40;52377:7;52386:18;52396:7;-1:-1:-1::0;;;;;5977:18:0;5950:7;5977:18;;;;;;;;;;;;5876:127;52386:18:::1;52365:11;:40::i;:::-;52420:19;;:15;52440:7:::0;52449:18:::1;52440:7:::0;-1:-1:-1;;;;;5977:18:0;5950:7;5977:18;;;;;;;;;;;;5876:127;52449:18:::1;52420:48;::::0;-1:-1:-1;;;;;;52420:48:0::1;::::0;;;;;;::::1;::::0;::::1;6511:25:1::0;;;;-1:-1:-1;;;;;6572:32:1;;;6552:18;;;6545:60;6621:18;;;6614:34;6484:18;;52420:48:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;52229:251;52516:7;-1:-1:-1::0;;;;;52495:36:0::1;;52525:5;52495:36;;;;1776:14:1::0;1769:22;1751:41;;1739:2;1724:18;;1611:187;52495:36:0::1;;;;;;;;52032:507:::0;;:::o;4586:100::-;4640:13;4673:5;4666:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4586:100;:::o;6752:169::-;6835:4;6852:39;210:10;6875:7;6884:6;6852:8;:39::i;:::-;-1:-1:-1;6909:4:0;6752:169;;;;;:::o;7403:355::-;7543:4;7560:36;7570:6;7578:9;7589:6;7560:9;:36::i;:::-;7607:121;7616:6;210:10;7638:89;7676:6;7638:89;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;7638:19:0;;;;;;:11;:19;;;;;;;;210:10;7638:33;;;;;;;;;;:37;:89::i;:::-;7607:8;:121::i;:::-;-1:-1:-1;7746:4:0;7403:355;;;;;:::o;30517:253::-;-1:-1:-1;;;;;30697:36:0;;30594:7;30697:36;;;:28;:36;;;;;;;;;5977:18;;;;;;;30619:25;;-1:-1:-1;;;25001:6:0;30619:131;;:115;;:63;;:48;;:25;:29;:48::i;:::-;:61;:63::i;:::-;:77;;:115::i;:::-;:129;:131::i;:::-;:143;;;;:::i;8167:218::-;210:10;8255:4;8304:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;8304:34:0;;;;;;;;;;8255:4;;8272:83;;8295:7;;8304:50;;8343:10;8304:38;:50::i;54924:542::-;55028:7;55050:6;55071;55092:7;55114;55136;55158;55180;55228:15;:20;;;;:22;;;;;;;;;;;;;1949:25:1;;1937:2;1922:18;;1803:177;55228:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55219:5;:31;55215:138;;-1:-1:-1;55275:42:0;;-1:-1:-1;;;55319:2:0;-1:-1:-1;55319:2:0;;-1:-1:-1;55275:42:0;;-1:-1:-1;55275:42:0;;-1:-1:-1;55275:42:0;;-1:-1:-1;55275:42:0;;-1:-1:-1;55275:42:0;55267:74;;55215:138;55383:36;;-1:-1:-1;;;55383:36:0;;:15;:36;;;7649:25:1;7690:18;;;7683:34;;;55365:15:0;;55383:29;;;;7622:18:1;;55383:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55365:54;;55439:19;55450:7;55439:10;:19::i;:::-;55432:26;;;;;;;;;;;;;;;;;54924:542;;;;;;;;;;:::o;20546:148::-;20116:6;;-1:-1:-1;;;;;20116:6:0;210:10;20116:22;20108:67;;;;-1:-1:-1;;;20108:67:0;;;;;;;:::i;:::-;20637:6:::1;::::0;20616:40:::1;::::0;20653:1:::1;::::0;-1:-1:-1;;;;;20637:6:0::1;::::0;20616:40:::1;::::0;20653:1;;20616:40:::1;20667:6;:19:::0;;-1:-1:-1;;;;;;20667:19:0::1;::::0;;20546:148::o;53296:131::-;53400:11;;53385:34;;;-1:-1:-1;;;53385:34:0;;;;53352:13;;-1:-1:-1;;;;;53400:11:0;;53385:32;;:34;;;;;53400:11;;53385:34;;;;;;;53400:11;53385:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;53385:34:0;;;;;;;;;;;;:::i;:::-;53378:41;;53296:131;:::o;28470:101::-;20116:6;;-1:-1:-1;;;;;20116:6:0;210:10;20116:22;20108:67;;;;-1:-1:-1;;;20108:67:0;;;;;;;:::i;:::-;28541:11:::1;:22:::0;;-1:-1:-1;;;;;;28541:22:0::1;-1:-1:-1::0;;;;;28541:22:0;;;::::1;::::0;;;::::1;::::0;;28470:101::o;29191:128::-;29256:7;29281:30;29304:6;29281:22;:30::i;4805:104::-;4861:13;4894:7;4887:14;;;;;:::i;51878:146::-;20116:6;;-1:-1:-1;;;;;20116:6:0;210:10;20116:22;20108:67;;;;-1:-1:-1;;;20108:67:0;;;;;;;:::i;:::-;52002:14:::1;5631:1:::0;52002:2:::1;:14;:::i;:::-;51993:23;::::0;:6;:23:::1;:::i;:::-;51959:31;:57:::0;-1:-1:-1;51878:146:0:o;8888:269::-;8981:4;8998:129;210:10;9021:7;9030:96;9069:15;9030:96;;;;;;;;;;;;;;;;;210:10;9030:25;;;;:11;:25;;;;;;;;-1:-1:-1;;;;;9030:34:0;;;;;;;;;;;;:38;:96::i;29538:172::-;-1:-1:-1;;;;;29675:26:0;;29615:7;29675:26;;;:18;:26;;;;;;29640:62;;:30;29694:6;29640:22;:30::i;:::-;:34;;:62::i;6216:175::-;6302:4;6319:42;210:10;6343:9;6354:6;6319:9;:42::i;57607:397::-;20116:6;;57725:4;;-1:-1:-1;;;;;20116:6:0;210:10;20116:22;20108:67;;;;-1:-1:-1;;;20108:67:0;;;;;;;:::i;:::-;57747:14:::1;57764:32;57788:7;57764:23;:32::i;:::-;57747:49:::0;-1:-1:-1;57813:10:0;;57809:163:::1;;-1:-1:-1::0;;;;;57840:23:0;::::1;;::::0;;;:14:::1;:23;::::0;;;;;;57866:15:::1;57840:41:::0;;57901:33;;::::1;;::::0;57840:23;57901:33:::1;::::0;::::1;::::0;57916:6;1949:25:1;;1937:2;1922:18;;1803:177;57901:33:0::1;;;;;;;;57956:4;57949:11;;;;;57809:163;-1:-1:-1::0;57991:5:0::1;::::0;57607:397;-1:-1:-1;;;57607:397:0:o;55716:491::-;20116:6;;-1:-1:-1;;;;;20116:6:0;210:10;20116:22;20108:67;;;;-1:-1:-1;;;20108:67:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;55805:30:0;::::1;;::::0;;;:21:::1;:30;::::0;;;;;::::1;;55852:7;55801:69;55900:31;;55886:10;:45;55882:267;;55948:32;55960:7;55969:10;55948:11;:32::i;:::-;55995:40;::::0;-1:-1:-1;;;55995:40:0;;:15:::1;:40;::::0;::::1;6511:25:1::0;-1:-1:-1;;;;;6572:32:1;;6552:18;;;6545:60;6621:18;;;6614:34;;;55995:19:0::1;::::0;::::1;::::0;6484:18:1;;55995:40:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;55882:267;;;56068:23;56080:7;56089:1;56068:11;:23::i;:::-;56106:31;::::0;-1:-1:-1;;;56106:31:0;;:15:::1;:31;::::0;::::1;6174:25:1::0;-1:-1:-1;;;;;6235:32:1;;6215:18;;;6208:60;56106:22:0::1;::::0;::::1;::::0;6147:18:1;;56106:31:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;55882:267;56161:38;56184:7;56194:4;56161:14;:38::i;:::-;;20186:1;55716:491:::0;;:::o;52547:496::-;20116:6;;-1:-1:-1;;;;;20116:6:0;210:10;20116:22;20108:67;;;;-1:-1:-1;;;20108:67:0;;;;;;;:::i;:::-;52662:4:::1;52646:12;:20;;:45;;;;;52686:5;52670:12;:21;;52646:45;52624:171;;;::::0;-1:-1:-1;;;52624:171:0;;10878:2:1;52624:171:0::1;::::0;::::1;10860:21:1::0;10917:2;10897:18;;;10890:30;10956:34;10936:18;;;10929:62;11027:34;11007:18;;;11000:62;-1:-1:-1;;;11078:19:1;;;11071:43;11131:19;;52624:171:0::1;10676:480:1::0;52624:171:0::1;52844:9;;52828:12;:25:::0;52806:137:::1;;;::::0;-1:-1:-1;;;52806:137:0;;11363:2:1;52806:137:0::1;::::0;::::1;11345:21:1::0;11402:2;11382:18;;;11375:30;11441:34;11421:18;;;11414:62;11512:32;11492:18;;;11485:60;11562:19;;52806:137:0::1;11161:426:1::0;52806:137:0::1;52990:9;::::0;52959:41:::1;::::0;52976:12;;52959:41:::1;::::0;;;::::1;53011:9;:24:::0;52547:496::o;20849:244::-;20116:6;;-1:-1:-1;;;;;20116:6:0;210:10;20116:22;20108:67;;;;-1:-1:-1;;;20108:67:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;20938:22:0;::::1;20930:73;;;::::0;-1:-1:-1;;;20930:73:0;;11794:2:1;20930:73:0::1;::::0;::::1;11776:21:1::0;11833:2;11813:18;;;11806:30;11872:34;11852:18;;;11845:62;-1:-1:-1;;;11923:18:1;;;11916:36;11969:19;;20930:73:0::1;11592:402:1::0;20930:73:0::1;21040:6;::::0;21019:38:::1;::::0;-1:-1:-1;;;;;21019:38:0;;::::1;::::0;21040:6:::1;::::0;21019:38:::1;::::0;21040:6:::1;::::0;21019:38:::1;21068:6;:17:::0;;-1:-1:-1;;;;;;21068:17:0::1;-1:-1:-1::0;;;;;21068:17:0;;;::::1;::::0;;;::::1;::::0;;20849:244::o;53435:1481::-;53896:38;;-1:-1:-1;;;53896:38:0;;:15;:38;;;6174:25:1;-1:-1:-1;;;;;6235:32:1;;6215:18;;;6208:60;53867:8:0;;53535:15;;;;;;;;;;;;;;53896:29;;;;6147:18:1;;53896:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53888:46;;-1:-1:-1;;53947:29:0;;54002:1;53993:5;:10;53989:517;;54041:18;;54032:5;54024:35;54020:475;;;54124:18;;54107:37;;:5;;:9;:37::i;:::-;54080:64;;54020:475;;;54271:18;;54220:15;:27;54185:32;;-1:-1:-1;54220:169:0;;54388:1;54220:169;;;54345:18;;54313:15;:27;:51;;:31;:51::i;:::-;54185:204;-1:-1:-1;54437:42:0;54185:204;54437:5;:42;:::i;:::-;54410:69;;54166:329;54020:475;54542:31;54565:7;54542:22;:31::i;:::-;54518:55;;54601:31;54624:7;54601:22;:31::i;:::-;-1:-1:-1;;;;;54661:23:0;;;;;;:14;:23;;;;;;54584:48;;-1:-1:-1;54661:23:0;-1:-1:-1;54713:17:0;:51;;54763:1;54713:51;;;54750:9;;54733:27;;:13;:27;:::i;:::-;54697:67;;54826:15;54810:13;:31;:98;;54907:1;54810:98;;;54857:34;:13;54875:15;54857:17;:34::i;:::-;54777:131;;53435:1481;;;;;;;;;:::o;56215:1384::-;56403:15;:27;56293:7;;;;;;56447:25;;;56443:91;;-1:-1:-1;;56503:18:0;;56497:1;;-1:-1:-1;56497:1:0;;-1:-1:-1;56489:33:0;;56443:91;56576:18;;56546:27;;56657:9;56639:27;;56679:18;56712:14;56743:736;56760:3;56750:7;:13;:50;;;;;56780:20;56767:10;:33;56750:50;56743:736;;;56817:21;;;;:::i;:::-;56882:15;:27;56817:21;;-1:-1:-1;56859:50:0;;;-1:-1:-1;56855:114:0;;56952:1;56930:23;;56855:114;56985:15;57003;:20;;57024:19;57003:41;;;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;57003:41:0;57078:23;;;:14;:23;;;;;;;;57003:41;;-1:-1:-1;57065:37:0;;:12;:37::i;:::-;57061:172;;;57127:38;57150:7;57160:4;57127:14;:38::i;:::-;57123:95;;;57190:8;;;;:::i;:::-;;;;57123:95;57249:12;;;;:::i;:::-;;;;57278:18;57299:9;57278:30;;57339:10;57329:7;:20;57325:106;;;57391:23;:7;57403:10;57391:11;:23::i;:::-;57380:35;;:7;:35;:::i;:::-;57370:45;;57325:106;57457:10;-1:-1:-1;56743:736:0;;-1:-1:-1;56743:736:0;;57491:18;:40;;;57552:10;;-1:-1:-1;57564:6:0;-1:-1:-1;57512:19:0;;-1:-1:-1;;;;56215:1384:0;;;;;;:::o;14151:471::-;14209:7;14454:1;14459;14454:6;14450:47;;-1:-1:-1;14484:1:0;14477:8;;14450:47;14509:9;14521:5;14525:1;14521;:5;:::i;:::-;14509:17;-1:-1:-1;14554:1:0;14545:5;14549:1;14509:17;14545:5;:::i;:::-;:10;14537:56;;;;-1:-1:-1;;;14537:56:0;;13012:2:1;14537:56:0;;;12994:21:1;13051:2;13031:18;;;13024:30;13090:34;13070:18;;;13063:62;-1:-1:-1;;;13141:18:1;;;13134:31;13182:19;;14537:56:0;12810:397:1;14537:56:0;14613:1;14151:471;-1:-1:-1;;;14151:471:0:o;12797:181::-;12855:7;;12887:5;12891:1;12887;:5;:::i;:::-;12875:17;;12916:1;12911;:6;;12903:46;;;;-1:-1:-1;;;12903:46:0;;13414:2:1;12903:46:0;;;13396:21:1;13453:2;13433:18;;;13426:30;13492:29;13472:18;;;13465:57;13539:18;;12903:46:0;13212:351:1;32545:452:0;-1:-1:-1;;;;;5977:18:0;;32621:22;5977:18;;;;;;;;;;;32678:27;;;32675:315;;;32718:26;32747:30;:10;32762:14;32747;:30::i;:::-;32718:59;;32788:45;32805:7;32814:18;32788:16;:45::i;:::-;32707:136;32675:315;;;32865:14;32852:10;:27;32849:141;;;32892:18;32913:30;:14;32932:10;32913:18;:30::i;:::-;32892:51;;32954:26;32960:7;32969:10;32954:5;:26::i;:::-;32881:109;32612:385;32545:452;;:::o;12014:380::-;-1:-1:-1;;;;;12150:19:0;;12142:68;;;;-1:-1:-1;;;12142:68:0;;13770:2:1;12142:68:0;;;13752:21:1;13809:2;13789:18;;;13782:30;13848:34;13828:18;;;13821:62;-1:-1:-1;;;13899:18:1;;;13892:34;13943:19;;12142:68:0;13568:400:1;12142:68:0;-1:-1:-1;;;;;12229:21:0;;12221:68;;;;-1:-1:-1;;;12221:68:0;;14175:2:1;12221:68:0;;;14157:21:1;14214:2;14194:18;;;14187:30;14253:34;14233:18;;;14226:62;-1:-1:-1;;;14304:18:1;;;14297:32;14346:19;;12221:68:0;13973:398:1;12221:68:0;-1:-1:-1;;;;;12302:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;12354:32;;1949:25:1;;;12354:32:0;;1922:18:1;12354:32:0;;;;;;;12014:380;;;:::o;51685:185::-;51799:63;;-1:-1:-1;;;51799:63:0;;14578:2:1;51799:63:0;;;14560:21:1;14617:2;14597:18;;;14590:30;14656:34;14636:18;;;14629:62;-1:-1:-1;;;14707:18:1;;;14700:43;14760:19;;51799:63:0;14376:409:1;13700:192:0;13786:7;13822:12;13814:6;;;;13806:29;;;;-1:-1:-1;;;13806:29:0;;;;;;;;:::i;:::-;-1:-1:-1;13846:9:0;13858:5;13862:1;13858;:5;:::i;:::-;13846:17;13700:192;-1:-1:-1;;;;;13700:192:0:o;19271:134::-;19327:6;19360:1;19377:6;;;;19369:15;;;;;18607:176;18663:6;;18693:5;18697:1;18693;:5;:::i;:::-;18682:16;;18723:1;18718;:6;;:16;;;;;18733:1;18728;:6;;18718:16;18717:38;;;;18744:1;18740;:5;:14;;;;;18753:1;18749;:5;18740:14;18709:47;;;;;19012:127;19068:7;19101:1;19096;:6;;19088:15;;;;;;-1:-1:-1;19129:1:0;19012:127::o;13261:136::-;13319:7;13346:43;13350:1;13353;13346:43;;;;;;;;;;;;;;;;;:3;:43::i;27203:1255::-;27276:7;27296:29;27328:28;27351:4;27328:22;:28::i;:::-;27296:60;-1:-1:-1;27371:25:0;;27367:1065;;-1:-1:-1;;;;;27440:24:0;;;;;;:18;:24;;;;;;:51;;27469:21;27440:28;:51::i;:::-;-1:-1:-1;;;;;27413:24:0;;;;;;:18;:24;;;;;;;:78;;;;27511:46;;;;;;27535:21;1949:25:1;;1937:2;1922:18;;1803:177;27511:46:0;;;;;;;;27590:6;;;;;;;;;-1:-1:-1;;;;;27590:6:0;-1:-1:-1;;;;;27590:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;27575:11;;-1:-1:-1;;;;;27575:11:0;;;:28;;;27572:806;;27624:12;27640:50;27662:4;27668:21;27640;:50::i;:::-;27623:67;;27713:7;27709:346;;27746:18;27769:4;-1:-1:-1;;;;;27769:9:0;27786:21;27814:4;27769:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27745:78;;;27850:13;27846:183;;-1:-1:-1;;;;;27919:24:0;;;;;;:18;:24;;;;;;:51;;27948:21;27919:28;:51::i;:::-;-1:-1:-1;;;;;27892:24:0;;;;;;;:18;:24;;;;;:78;;;;-1:-1:-1;27892:24:0;;27203:1255;-1:-1:-1;;;27203:1255:0:o;27846:183::-;27722:333;27709:346;27604:466;27572:806;;;28108:12;28125:4;-1:-1:-1;;;;;28125:9:0;28142:21;28170:4;28125:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28107:72;;;28202:7;28198:165;;-1:-1:-1;;;;;28261:24:0;;;;;;:18;:24;;;;;;:51;;28290:21;28261:28;:51::i;:::-;-1:-1:-1;;;;;28234:24:0;;;;;;;:18;:24;;;;;:78;;;;-1:-1:-1;28234:24:0;;27203:1255;-1:-1:-1;;27203:1255:0:o;28198:165::-;28088:290;28399:21;27203:1255;-1:-1:-1;;27203:1255:0:o;27367:1065::-;-1:-1:-1;28449:1:0;;27203:1255;-1:-1:-1;;27203:1255:0:o;18343:176::-;18399:6;;18429:5;18433:1;18429;:5;:::i;:::-;18418:16;;18459:1;18454;:6;;:16;;;;;18469:1;18464;:6;;18454:16;18453:38;;;;18480:1;18476;:5;:14;;;;;18489:1;18485;:5;18445:47;;;;;55474:234;55541:4;55578:15;55562:13;:31;55558:76;;;-1:-1:-1;55617:5:0;;55474:234;-1:-1:-1;55474:234:0:o;55558:76::-;55691:9;;55653:34;:15;55673:13;55653:19;:34::i;:::-;:47;;;55474:234;-1:-1:-1;;55474:234:0:o;31694:290::-;31779:38;31802:7;31811:5;31779:22;:38::i;:::-;31868:108;31921:53;31922:36;31952:5;31922:25;;:29;;:36;;;;:::i;31921:53::-;-1:-1:-1;;;;;31868:37:0;;;;;;:28;:37;;;;;;;:51;:108::i;:::-;-1:-1:-1;;;;;31828:37:0;;;;;;;:28;:37;;;;;:148;;;;-1:-1:-1;31694:290:0:o;32269:268::-;32343:27;32355:7;32364:5;32343:11;:27::i;:::-;32421:108;32474:53;32475:36;32505:5;32475:25;;:29;;:36;;;;:::i;32474:53::-;-1:-1:-1;;;;;32421:37:0;;;;;;:28;:37;;;;;;;:51;:108::i;28581:391::-;28700:16;;;28714:1;28700:16;;;;;;;;28657:4;;;;28700:16;28714:1;28700:16;;;;;;;;-1:-1:-1;;28739:6:0;;:13;;;-1:-1:-1;;;28739:13:0;;;;28676:40;;-1:-1:-1;;;;;;28739:6:0;;;;:11;;-1:-1:-1;28739:13:0;;;;;;;;;;;;;;:6;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28729:4;28734:1;28729:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;28729:23:0;;;:7;;;;;;;;;:23;28775:11;;28765:7;;28775:11;;;28765:4;;28775:11;;28765:7;;;;;;:::i;:::-;-1:-1:-1;;;;;28765:21:0;;;:7;;;;;;;;;:21;28805:6;;;:28;28841:3;28805:6;28849:4;28855;28861:19;:15;28879:1;28861:19;:::i;:::-;28805:76;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;28805:76:0;;;;;;;;;;;;:::i;:::-;;;28801:164;;28948:5;28941:12;;;;;28801:164;;28903:4;28896:11;;;;;10430:395;-1:-1:-1;;;;;10525:21:0;;10517:71;;;;-1:-1:-1;;;10517:71:0;;17394:2:1;10517:71:0;;;17376:21:1;17433:2;17413:18;;;17406:30;17472:34;17452:18;;;17445:62;-1:-1:-1;;;17523:18:1;;;17516:35;17568:19;;10517:71:0;17192:401:1;10517:71:0;10601:49;10630:1;10634:7;10643:6;10601:20;:49::i;:::-;10678:12;;:24;;10695:6;10678:16;:24::i;:::-;10663:12;:39;-1:-1:-1;;;;;10734:18:0;;:9;:18;;;;;;;;;;;:30;;10757:6;10734:22;:30::i;:::-;-1:-1:-1;;;;;10713:18:0;;:9;:18;;;;;;;;;;;:51;;;;10780:37;;1949:25:1;;;10713:18:0;;:9;;10780:37;;1922:18:1;10780:37:0;;;;;;;;10430:395;;:::o;11158:418::-;-1:-1:-1;;;;;11242:21:0;;11234:67;;;;-1:-1:-1;;;11234:67:0;;17800:2:1;11234:67:0;;;17782:21:1;17839:2;17819:18;;;17812:30;17878:34;17858:18;;;17851:62;-1:-1:-1;;;17929:18:1;;;17922:31;17970:19;;11234:67:0;17598:397:1;11234:67:0;11314:49;11335:7;11352:1;11356:6;11314:20;:49::i;:::-;11397:68;11420:6;11397:68;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11397:18:0;;:9;:18;;;;;;;;;;;;:68;:22;:68::i;:::-;-1:-1:-1;;;;;11376:18:0;;:9;:18;;;;;;;;;;:89;11491:12;;:24;;11508:6;11491:16;:24::i;:::-;11476:12;:39;11531:37;;1949:25:1;;;11557:1:0;;-1:-1:-1;;;;;11531:37:0;;;;;1937:2:1;1922:18;11531:37:0;1803:177:1;14:131;-1:-1:-1;;;;;89:31:1;;79:42;;69:70;;135:1;132;125:12;69:70;14:131;:::o;150:160::-;215:20;;271:13;;264:21;254:32;;244:60;;300:1;297;290:12;244:60;150:160;;;:::o;315:315::-;380:6;388;441:2;429:9;420:7;416:23;412:32;409:52;;;457:1;454;447:12;409:52;496:9;483:23;515:31;540:5;515:31;:::i;:::-;565:5;-1:-1:-1;589:35:1;620:2;605:18;;589:35;:::i;:::-;579:45;;315:315;;;;;:::o;635:250::-;720:1;730:113;744:6;741:1;738:13;730:113;;;820:11;;;814:18;801:11;;;794:39;766:2;759:10;730:113;;;-1:-1:-1;;877:1:1;859:16;;852:27;635:250::o;890:396::-;1039:2;1028:9;1021:21;1002:4;1071:6;1065:13;1114:6;1109:2;1098:9;1094:18;1087:34;1130:79;1202:6;1197:2;1186:9;1182:18;1177:2;1169:6;1165:15;1130:79;:::i;:::-;1270:2;1249:15;-1:-1:-1;;1245:29:1;1230:45;;;;1277:2;1226:54;;890:396;-1:-1:-1;;890:396:1:o;1291:315::-;1359:6;1367;1420:2;1408:9;1399:7;1395:23;1391:32;1388:52;;;1436:1;1433;1426:12;1388:52;1475:9;1462:23;1494:31;1519:5;1494:31;:::i;:::-;1544:5;1596:2;1581:18;;;;1568:32;;-1:-1:-1;;;1291:315:1:o;1985:247::-;2044:6;2097:2;2085:9;2076:7;2072:23;2068:32;2065:52;;;2113:1;2110;2103:12;2065:52;2152:9;2139:23;2171:31;2196:5;2171:31;:::i;2237:456::-;2314:6;2322;2330;2383:2;2371:9;2362:7;2358:23;2354:32;2351:52;;;2399:1;2396;2389:12;2351:52;2438:9;2425:23;2457:31;2482:5;2457:31;:::i;:::-;2507:5;-1:-1:-1;2564:2:1;2549:18;;2536:32;2577:33;2536:32;2577:33;:::i;:::-;2237:456;;2629:7;;-1:-1:-1;;;2683:2:1;2668:18;;;;2655:32;;2237:456::o;2887:180::-;2946:6;2999:2;2987:9;2978:7;2974:23;2970:32;2967:52;;;3015:1;3012;3005:12;2967:52;-1:-1:-1;3038:23:1;;2887:180;-1:-1:-1;2887:180:1:o;4314:388::-;4382:6;4390;4443:2;4431:9;4422:7;4418:23;4414:32;4411:52;;;4459:1;4456;4449:12;4411:52;4498:9;4485:23;4517:31;4542:5;4517:31;:::i;:::-;4567:5;-1:-1:-1;4624:2:1;4609:18;;4596:32;4637:33;4596:32;4637:33;:::i;:::-;4689:7;4679:17;;;4314:388;;;;;:::o;5255:127::-;5316:10;5311:3;5307:20;5304:1;5297:31;5347:4;5344:1;5337:15;5371:4;5368:1;5361:15;5387:217;5427:1;5453;5443:132;;5497:10;5492:3;5488:20;5485:1;5478:31;5532:4;5529:1;5522:15;5560:4;5557:1;5550:15;5443:132;-1:-1:-1;5589:9:1;;5387:217::o;5609:356::-;5811:2;5793:21;;;5830:18;;;5823:30;5889:34;5884:2;5869:18;;5862:62;5956:2;5941:18;;5609:356::o;6659:380::-;6738:1;6734:12;;;;6781;;;6802:61;;6856:4;6848:6;6844:17;6834:27;;6802:61;6909:2;6901:6;6898:14;6878:18;6875:38;6872:161;;6955:10;6950:3;6946:20;6943:1;6936:31;6990:4;6987:1;6980:15;7018:4;7015:1;7008:15;6872:161;;6659:380;;;:::o;7256:184::-;7326:6;7379:2;7367:9;7358:7;7354:23;7350:32;7347:52;;;7395:1;7392;7385:12;7347:52;-1:-1:-1;7418:16:1;;7256:184;-1:-1:-1;7256:184:1:o;7728:251::-;7798:6;7851:2;7839:9;7830:7;7826:23;7822:32;7819:52;;;7867:1;7864;7857:12;7819:52;7899:9;7893:16;7918:31;7943:5;7918:31;:::i;7984:127::-;8045:10;8040:3;8036:20;8033:1;8026:31;8076:4;8073:1;8066:15;8100:4;8097:1;8090:15;8116:275;8187:2;8181:9;8252:2;8233:13;;-1:-1:-1;;8229:27:1;8217:40;;8287:18;8272:34;;8308:22;;;8269:62;8266:88;;;8334:18;;:::i;:::-;8370:2;8363:22;8116:275;;-1:-1:-1;8116:275:1:o;8396:719::-;8476:6;8529:2;8517:9;8508:7;8504:23;8500:32;8497:52;;;8545:1;8542;8535:12;8497:52;8578:9;8572:16;8607:18;8648:2;8640:6;8637:14;8634:34;;;8664:1;8661;8654:12;8634:34;8702:6;8691:9;8687:22;8677:32;;8747:7;8740:4;8736:2;8732:13;8728:27;8718:55;;8769:1;8766;8759:12;8718:55;8798:2;8792:9;8820:2;8816;8813:10;8810:36;;;8826:18;;:::i;:::-;8868:53;8911:2;8892:13;;-1:-1:-1;;8888:27:1;8917:2;8884:36;8868:53;:::i;:::-;8855:66;;8944:2;8937:5;8930:17;8984:7;8979:2;8974;8970;8966:11;8962:20;8959:33;8956:53;;;9005:1;9002;8995:12;8956:53;9018:67;9082:2;9077;9070:5;9066:14;9061:2;9057;9053:11;9018:67;:::i;:::-;-1:-1:-1;9104:5:1;8396:719;-1:-1:-1;;;;8396:719:1:o;9120:422::-;9209:1;9252:5;9209:1;9266:270;9287:7;9277:8;9274:21;9266:270;;;9346:4;9342:1;9338:6;9334:17;9328:4;9325:27;9322:53;;;9355:18;;:::i;:::-;9405:7;9395:8;9391:22;9388:55;;;9425:16;;;;9388:55;9504:22;;;;9464:15;;;;9266:270;;;9270:3;9120:422;;;;;:::o;9547:806::-;9596:5;9626:8;9616:80;;-1:-1:-1;9667:1:1;9681:5;;9616:80;9715:4;9705:76;;-1:-1:-1;9752:1:1;9766:5;;9705:76;9797:4;9815:1;9810:59;;;;9883:1;9878:130;;;;9790:218;;9810:59;9840:1;9831:10;;9854:5;;;9878:130;9915:3;9905:8;9902:17;9899:43;;;9922:18;;:::i;:::-;-1:-1:-1;;9978:1:1;9964:16;;9993:5;;9790:218;;10092:2;10082:8;10079:16;10073:3;10067:4;10064:13;10060:36;10054:2;10044:8;10041:16;10036:2;10030:4;10027:12;10023:35;10020:77;10017:159;;;-1:-1:-1;10129:19:1;;;10161:5;;10017:159;10208:34;10233:8;10227:4;10208:34;:::i;:::-;10278:6;10274:1;10270:6;10266:19;10257:7;10254:32;10251:58;;;10289:18;;:::i;:::-;10327:20;;9547:806;-1:-1:-1;;;9547:806:1:o;10358:140::-;10416:5;10445:47;10486:4;10476:8;10472:19;10466:4;10445:47;:::i;10503:168::-;10576:9;;;10607;;10624:15;;;10618:22;;10604:37;10594:71;;10645:18;;:::i;12187:216::-;12251:9;;;12279:11;;;12226:3;12309:9;;12337:10;;12333:19;;12362:10;;12354:19;;12330:44;12327:70;;;12377:18;;:::i;:::-;12327:70;;12187:216;;;;:::o;12408:125::-;12473:9;;;12494:10;;;12491:36;;;12507:18;;:::i;12538:135::-;12577:3;12598:17;;;12595:43;;12618:18;;:::i;:::-;-1:-1:-1;12665:1:1;12654:13;;12538:135::o;12678:127::-;12739:10;12734:3;12730:20;12727:1;12720:31;12770:4;12767:1;12760:15;12794:4;12791:1;12784:15;14790:128;14857:9;;;14878:11;;;14875:37;;;14892:18;;:::i;15133:200::-;15199:9;;;15172:4;15227:9;;15255:10;;15267:12;;;15251:29;15290:12;;;15282:21;;15248:56;15245:82;;;15307:18;;:::i;15338:908::-;15572:4;15620:3;15609:9;15605:19;15651:6;15640:9;15633:25;15677:2;15715:3;15710:2;15699:9;15695:18;15688:31;15739:6;15774;15768:13;15805:6;15797;15790:22;15843:3;15832:9;15828:19;15821:26;;15882:2;15874:6;15870:15;15856:29;;15903:1;15913:195;15927:6;15924:1;15921:13;15913:195;;;15992:13;;-1:-1:-1;;;;;15988:39:1;15976:52;;16083:15;;;;16048:12;;;;16024:1;15942:9;15913:195;;;-1:-1:-1;;;;;;;16164:32:1;;;;16159:2;16144:18;;16137:60;-1:-1:-1;;;16228:2:1;16213:18;16206:34;16125:3;15338:908;-1:-1:-1;;15338:908:1:o;16251:936::-;16346:6;16377:2;16420;16408:9;16399:7;16395:23;16391:32;16388:52;;;16436:1;16433;16426:12;16388:52;16469:9;16463:16;16498:18;16539:2;16531:6;16528:14;16525:34;;;16555:1;16552;16545:12;16525:34;16593:6;16582:9;16578:22;16568:32;;16638:7;16631:4;16627:2;16623:13;16619:27;16609:55;;16660:1;16657;16650:12;16609:55;16689:2;16683:9;16711:2;16707;16704:10;16701:36;;;16717:18;;:::i;:::-;16763:2;16760:1;16756:10;16746:20;;16786:28;16810:2;16806;16802:11;16786:28;:::i;:::-;16848:15;;;16918:11;;;16914:20;;;16879:12;;;;16946:19;;;16943:39;;;16978:1;16975;16968:12;16943:39;17002:11;;;;17022:135;17038:6;17033:3;17030:15;17022:135;;;17104:10;;17092:23;;17055:12;;;;17135;;;;17022:135;;;17176:5;16251:936;-1:-1:-1;;;;;;;;16251:936:1:o

Swarm Source

ipfs://c6774a4d7ae731b7105c89babd0ef1d5ff11e3503a14ea58a588acc1ad200d37
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.