POL Price: $0.378676 (+0.61%)
Gas: 36 GWei
 

Overview

Max Total Supply

1,000,000,000 HRVST

Holders

132

Total Transfers

-

Market

Price

$0.00 @ 0.000000 POL

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
HarvestProtocol

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
cancun EvmVersion, MIT license
File 1 of 12 : HarvestProtocol.sol
/*

  Harvest Protocol

  🌾🟪 Welcome to the pioneering Hold-to-Earn platform on Polygon!
  
  Web: https://hrvstprotocol.app/
  X: https://twitter.com/HRVSTprotocol
  Telegram: https://t.me/HRVSTprotocol

*/

// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import "./CF_Common.sol";
import "./CF_Ownable.sol";
import "./CF_ERC20.sol";
import "./CF_Recoverable.sol";
import "./CF_MaxTx.sol";
import "./CF_MaxBalance.sol";
import "./CF_Taxable.sol";
import "./CF_DEXRouterV2.sol";

contract HarvestProtocol is CF_Common, CF_Ownable, CF_ERC20, CF_Recoverable, CF_MaxTx, CF_MaxBalance, CF_Taxable, CF_DEXRouterV2 {
  constructor() {
    _name = unicode"Harvest Protocol";
    _symbol = unicode"HRVST";
    _decimals = 18;
    _totalSupply = 1000000000000000000000000000; // 1,000,000,000 HRVST

    _holder[address(this)].exists = true;
    _holders.push(address(this));

    _transferOwnership(0x267f44DA6305C82f47b5aDB1Af35860bDB3f1c86);
    _transferInitialSupply(0x267f44DA6305C82f47b5aDB1Af35860bDB3f1c86, 100000); // 100%
    _setDEXRouterV2(0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff, 0x267f44DA6305C82f47b5aDB1Af35860bDB3f1c86);
    _setTaxToken(0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270);
    _setDividendReflection(0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270);
    _autoSwapEnabled = true;
    _setAutoSwapPercent(100, 300); // 0.1% -> 0.3% of total supply
    _setAutoAddLiquidityPercent(100, 100000); // 0.1% -> 100% of total supply
    _minDividendDistributionHolderBalance = 1000000000000000000; // 1 HRVST
    _minDividendDistributionPercent = 100; // 0.1% of total supply
    _gasLimitForDividendDistribution = 300000;

    _setTaxBeneficiary(1, 0x372a75D1e50D6D3c25810328d010FDa2d284264c, [ uint24(0), uint24(2000), uint24(2000) ]);
    _setTaxBeneficiary(2, address(0), [ uint24(0), uint24(6000), uint24(6000) ]);
    _setMaxTxPercent(1000); // 1% of total supply
    _setMaxBalancePercent(1000); // 1% of total supply

    _initialized = true;
  }

  function _transfer(address from, address to, uint256 amount) internal virtual override {
    if (!_distributing && !_swapping && (from != _dex.pair && from != _dex.router)) {
      _autoSwap(false);
      _autoTaxDistribute();
    }

    if (amount > 0 && from != _owner && to != _owner && from != address(this) && to != address(this) && to != _dex.router) {
      require((from != _dex.pair && to != _dex.pair) || ((from == _dex.pair || to == _dex.pair) && _tradingEnabled > 0), "Trading disabled");

      unchecked {
        require(_maxTxAmount == 0 || amount <= _maxTxAmount, "Exceeds maxTx");
        require(_maxBalanceAmount == 0 || to == address(this) || (to == _dex.pair || to == _dex.router) || _balance[to] + amount <= _maxBalanceAmount, "Exceeds maxBalance");

        if (!_suspendTaxes && !_distributing && !_swapping) {
          uint256 appliedTax;
          uint8 taxType;

          if (from == _dex.pair || to == _dex.pair) { taxType = from == _dex.pair ? 1 : 2; }

          for (uint8 i = 1; i < 6; i++) {
            uint256 percent = uint256(taxType > 0 ? (taxType == 1 ? _taxBeneficiary[i].percent[1] : _taxBeneficiary[i].percent[2]) : _taxBeneficiary[i].percent[0]);

            if (percent == 0) { continue; }

            uint256 taxAmount = _percentage(amount, percent);

            super._transfer(from, address(this), taxAmount);

            if (_taxBeneficiary[i].account == _dex.pair) {
              _amountForLiquidity += taxAmount;
            } else {
              _taxBeneficiary[i].unclaimed += taxAmount;

              if (_taxBeneficiary[i].account == address(0)) {
                _amountForDividendDistribution += taxAmount;
                _totalDividendsUnclaimed += taxAmount;
              } else {
                _amountForTaxDistribution += taxAmount;
                _totalTaxUnclaimed += taxAmount;
              }
            }

            appliedTax += taxAmount;
          }

          if (appliedTax > 0) {
            _totalTaxCollected += appliedTax;

            amount -= appliedTax;
          }
        }
      }
    }

    super._transfer(from, to, amount);

    if (amount > 0 && !_holder[to].exists) {
      _holder[to].exists = true;
      _holders.push(to);
    }
  }

  function _transferInitialSupply(address account, uint24 percent) private {
    require(!_initialized);

    uint256 amount = _percentage(_totalSupply, uint256(percent));

    _balance[account] = amount;
    _holder[account].exists = true;
    _holders.push(account);

    emit Transfer(address(0), account, amount);
  }

  /// @notice Returns a list specifying the renounce status of each feature
  function renounced() external view returns (bool MaxTx, bool MaxBalance, bool DEXRouterV2, bool Taxable) {
    return (_renounced.MaxTx, _renounced.MaxBalance, _renounced.DEXRouterV2, _renounced.Taxable);
  }

  /// @notice Returns basic information about this Smart-Contract
  function info() external view returns (string memory name, string memory symbol, uint8 decimals, address owner, uint256 totalSupply, string memory version) {
    return (_name, _symbol, _decimals, _owner, _totalSupply, _version);
  }

  receive() external payable { }
  fallback() external payable { }
}

/*
   ________          _       ______           __                  
  / ____/ /_  ____ _(_)___  / ____/___ ______/ /_____  _______  __
 / /   / __ \/ __ `/ / __ \/ /_  / __ `/ ___/ __/ __ \/ ___/ / / /
/ /___/ / / / /_/ / / / / / __/ / /_/ / /__/ /_/ /_/ / /  / /_/ / 
\____/_/ /_/\__,_/_/_/ /_/_/    \__,_/\___/\__/\____/_/   \__, /  
                                                         /____/   

  Smart-Contract generated by ChainFactory.app

  By using this Smart-Contract generated by ChainFactory.app, you
  acknowledge and agree that ChainFactory shall not be liable for
  any damages arising from the use of this Smart-Contract,
  including but not limited to any damages resulting from any
  malicious or illegal use of the Smart-Contract by any third
  party or by the owner.

  The owner of the Smart-Contract generated by ChainFactory.app
  agrees not to misuse the Smart-Contract, including but not
  limited to:

  - Using the Smart-Contract to engage in any illegal or
    fraudulent activity, including but not limited to scams,
    theft, or money laundering.

  - Using the Smart-Contract in any manner that could cause harm
    to others, including but not limited to disrupting financial
    markets or causing financial loss to others.

  - Using the Smart-Contract to infringe upon the intellectual
    property rights of others, including but not limited to
    copyright, trademark, or patent infringement.

  The owner of the Smart-Contract generated by ChainFactory.app
  acknowledges that any misuse of the Smart-Contract may result in
  legal action, and agrees to indemnify and hold harmless
  ChainFactory from any and all claims, damages, or expenses
  arising from any such misuse.

*/

File 2 of 12 : IDEXV2.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

interface IDEXRouterV2 {
  function factory() external pure returns (address);
  function WETH() external pure returns (address);
  function addLiquidityETH(address token, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline) external payable returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);
  function swapExactTokensForETHSupportingFeeOnTransferTokens(uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) external;
  function swapExactTokensForTokensSupportingFeeOnTransferTokens(uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) external;
}

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

File 3 of 12 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

interface IERC20 {
  function balanceOf(address account) external view returns (uint256);
  function transfer(address to, uint256 amount) external returns (bool);
  function approve(address spender, uint256 amount) external returns (bool);
}

File 4 of 12 : IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

interface IERC721 {
  function safeTransferFrom(address from, address to, uint256 tokenId) external returns (bool);
}

File 5 of 12 : CF_ERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import "./CF_Common.sol";

abstract contract CF_ERC20 is CF_Common {
  string internal _name;
  string internal _symbol;

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

  function name() external view returns (string memory) {
    return _name;
  }

  function symbol() external view returns (string memory) {
    return _symbol;
  }

  function decimals() external view returns (uint8) {
    return _decimals;
  }

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

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

  function allowance(address owner, address spender) public view returns (uint256) {
    return _allowance[owner][spender];
  }

  function approve(address spender, uint256 amount) external returns (bool) {
    _approve(msg.sender, spender, amount);

    return true;
  }

  function transfer(address to, uint256 amount) external returns (bool) {
    _transfer(msg.sender, to, amount);

    return true;
  }

  function transferFrom(address from, address to, uint256 amount) external returns (bool) {
    _spendAllowance(from, msg.sender, amount);
    _transfer(from, to, amount);

    return true;
  }

  function increaseAllowance(address spender, uint256 addedValue) external returns (bool) {
    unchecked {
      _approve(msg.sender, spender, allowance(msg.sender, spender) + addedValue);
    }

    return true;
  }

  function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool) {
    uint256 currentAllowance = allowance(msg.sender, spender);

    require(currentAllowance >= subtractedValue, "Negative allowance");

    unchecked {
      _approve(msg.sender, spender, currentAllowance - subtractedValue);
    }

    return true;
  }

  function _approve(address owner, address spender, uint256 amount) internal {
    _allowance[owner][spender] = amount;

    emit Approval(owner, spender, amount);
  }

  function _spendAllowance(address owner, address spender, uint256 amount) internal {
    uint256 currentAllowance = allowance(owner, spender);

    require(currentAllowance >= amount, "Insufficient allowance");

    unchecked {
      _approve(owner, spender, currentAllowance - amount);
    }
  }

  function _transfer(address from, address to, uint256 amount) internal virtual {
    require(from != address(0) && to != address(0), "Transfer from/to zero address");
    require(_balance[from] >= amount, "Exceeds balance");

    if (amount > 0) {
      unchecked {
        _balance[from] -= amount;
        _balance[to] += amount;
      }
    }

    emit Transfer(from, to, amount);
  }
}

File 6 of 12 : CF_MaxTx.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import "./CF_Common.sol";
import "./CF_Ownable.sol";

abstract contract CF_MaxTx is CF_Common, CF_Ownable {
  event SetMaxTxPercent(uint24 percent);
  event RenouncedMaxTx();

  /// @notice Permanently renounce and prevent the owner from being able to update the max. transferable amount
  /// @dev Existing settings will continue to be effective
  function renounceMaxTx() external onlyOwner {
    _renounced.MaxTx = true;

    emit RenouncedMaxTx();
  }

  /// @notice Percentage of the max. transferable amount, depending on total supply
  function getMaxTxPercent() external view returns (uint24) {
    return _maxTxPercent;
  }

  /// @notice Set the max. percentage of a transferable amount, depending on total supply
  /// @param percent Desired percentage, multiplied by denominator (min. 0.1% of total supply, 0 to disable)
  function setMaxTxPercent(uint24 percent) external onlyOwner {
    require(!_renounced.MaxTx);

    unchecked {
      require(percent == 0 || (percent >= 100 && percent <= 100 * _denominator));
    }

    _setMaxTxPercent(percent);

    emit SetMaxTxPercent(percent);
  }

  function _setMaxTxPercent(uint24 percent) internal {
    _maxTxPercent = percent;
    _maxTxAmount = percent > 0 ? _percentage(_totalSupply, uint256(percent)) : 0;

    if (!_initialized) { emit SetMaxTxPercent(percent); }
  }
}

File 7 of 12 : CF_Common.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import "./IDEXV2.sol";
import "./IERC20.sol";
import "./IERC721.sol";

abstract contract CF_Common {
  string internal constant _version = "1.0.2";

  mapping(address => uint256) internal _balance;
  mapping(address => mapping(address => uint256)) internal _allowance;
  mapping(address => holderAccount) internal _holder;
  mapping(uint8 => taxBeneficiary) internal _taxBeneficiary;
  mapping(address => uint256) internal _totalDividendsDistributedPerReflectionToken;
  mapping(address => uint256) internal _tokensForDividendDistribution;
  mapping(address => uint256) internal _tokensForTaxDistribution;

  address[] internal _holders;

  bool internal _autoSwapEnabled;
  bool internal _swapping;
  bool internal _suspendTaxes;
  bool internal _distributing;
  bool internal immutable _initialized;

  uint8 internal immutable _decimals;
  uint24 internal constant _denominator = 1000;
  uint24 internal _maxTxPercent;
  uint24 internal _maxBalancePercent;
  uint24 internal _totalTxTax;
  uint24 internal _totalBuyTax;
  uint24 internal _totalSellTax;
  uint24 internal _minDividendDistributionPercent;
  uint24 internal _minAutoSwapPercent;
  uint24 internal _maxAutoSwapPercent;
  uint24 internal _minAutoAddLiquidityPercent;
  uint24 internal _maxAutoAddLiquidityPercent;
  uint32 internal _lastTaxDistribution;
  uint32 internal _tradingEnabled;
  uint32 internal _lastSwap;
  uint256 internal _totalSupply;
  uint256 internal _maxTxAmount;
  uint256 internal _maxBalanceAmount;
  uint256 internal _minAutoSwapAmount;
  uint256 internal _maxAutoSwapAmount;
  uint256 internal _minAutoAddLiquidityAmount;
  uint256 internal _maxAutoAddLiquidityAmount;
  uint256 internal _amountForLiquidity;
  uint256 internal _ethForLiquidity;
  uint256 internal _totalTaxCollected;
  uint256 internal _totalTaxUnclaimed;
  uint256 internal _totalDividendsDistributed;
  uint256 internal _totalDividendsUnclaimed;
  uint256 internal _gasLimitForDividendDistribution;
  uint256 internal _minDividendDistributionHolderBalance;
  uint256 internal _lastDividendDistributionHolderIndex;
  uint256 internal _amountForTaxDistribution;
  uint256 internal _amountForDividendDistribution;
  uint256 internal _amountSwappedForTaxDistribution;
  uint256 internal _amountSwappedForDividendDistribution;
  uint256 internal _ethForTaxDistribution;
  uint256 internal _ethForDividendDistribution;

  struct Renounced {
    bool MaxTx;
    bool MaxBalance;
    bool Taxable;
    bool DEXRouterV2;
  }

  struct holderAccount {
    bool exists;
    mapping(address => uint256) dividends;
  }

  struct taxBeneficiary {
    bool exists;
    address account;
    uint24[3] percent; // 0: tx, 1: buy, 2: sell
    uint256 unclaimed;
  }

  struct DEXRouterV2 {
    address router;
    address pair;
    address WETH;
    address receiver;
  }

  Renounced internal _renounced;
  IERC20 internal _taxToken;
  IERC20 internal _dividendToken;
  DEXRouterV2 internal _dex;

  function _percentage(uint256 amount, uint256 bps) internal pure returns (uint256) {
    unchecked {
      return (amount * bps) / (100 * uint256(_denominator));
    }
  }

  function _timestamp() internal view returns (uint32) {
    unchecked {
      return uint32(block.timestamp % 2**32);
    }
  }

  function denominator() external pure returns (uint24) {
    return _denominator;
  }

  function version() external pure returns (string memory) {
    return _version;
  }
}

File 8 of 12 : CF_Ownable.sol
// SPDX-License-Identifier: MIT

import "./CF_Common.sol";

pragma solidity 0.8.24;

abstract contract CF_Ownable is CF_Common {
  address internal _owner;

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

  modifier onlyOwner() {
    require(_owner == msg.sender, "Unauthorized");

    _;
  }

  function owner() external view returns (address) {
    return _owner;
  }

  function renounceOwnership() external onlyOwner {
    _renounced.MaxTx = true;
    _renounced.MaxBalance = true;
    _renounced.Taxable = true;
    _renounced.DEXRouterV2 = true;

    _transferOwnership(address(0));
  }

  function transferOwnership(address newOwner) external onlyOwner {
    require(newOwner != address(0));

    _transferOwnership(newOwner);
  }

  function _transferOwnership(address newOwner) internal {
    address oldOwner = _owner;
    _owner = newOwner;

    emit OwnershipTransferred(oldOwner, newOwner);
  }
}

File 9 of 12 : CF_Taxable.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import "./CF_Common.sol";
import "./CF_Ownable.sol";
import "./CF_ERC20.sol";

abstract contract CF_Taxable is CF_Common, CF_Ownable, CF_ERC20 {
  event SetTaxBeneficiary(uint8 slot, address account, uint24[3] percent);
  event TaxDistributed(uint256 amount);
  event DividendsDistributed(uint256 amount, uint256 iterations);
  event RenouncedTaxable();

  struct taxBeneficiaryView {
    address account;
    uint24[3] percent;
    uint256 unclaimed;
  }

  modifier lockDistributing {
    _distributing = true;
    _;
    _distributing = false;
  }

  /// @notice Permanently renounce and prevent the owner from being able to update the tax features
  /// @dev Existing settings will continue to be effective
  function renounceTaxable() external onlyOwner {
    _renounced.Taxable = true;

    emit RenouncedTaxable();
  }

  /// @notice Total amount of taxes collected so far
  function totalTaxCollected() external view returns (uint256) {
    return _totalTaxCollected;
  }
  /// @notice Tax applied per transfer
  /// @dev Taking in consideration your wallet address
  function txTax() external view returns (uint24) {
    return txTax(msg.sender);
  }

  /// @notice Tax applied per transfer
  /// @param from Sender address
  function txTax(address from) public view returns (uint24) {
    unchecked {
      return from == address(this) || from == _dex.pair ? 0 : _totalTxTax;
    }
  }

  /// @notice Tax applied for buying
  /// @dev Taking in consideration your wallet address
  function buyTax() external view returns (uint24) {
    return buyTax(msg.sender);
  }

  /// @notice Tax applied for buying
  /// @param from Buyer's address
  function buyTax(address from) public view returns (uint24) {
    if (_suspendTaxes) { return 0; }

    unchecked {
      return from == address(this) || from == _dex.pair ? 0 : _totalBuyTax;
    }
  }
  /// @notice Tax applied for selling
  /// @dev Taking in consideration your wallet address
  function sellTax() external view returns (uint24) {
    return sellTax(msg.sender);
  }

  /// @notice Tax applied for selling
  /// @param to Seller's address
  function sellTax(address to) public view returns (uint24) {
    if (_suspendTaxes) { return 0; }

    unchecked {
      return to == address(this) || to == _owner || to == _dex.pair || to == _dex.router ? 0 : _totalSellTax;
    }
  }

  /// @notice List of all tax beneficiaries and their assigned percentage, according to type of transfer
  /// @custom:return `list[].account` Beneficiary address
  /// @custom:return `list[].percent[3]` Index 0 is for tx tax, 1 is for buy tax, 2 is for sell tax, multiplied by denominator
  function listTaxBeneficiaries() external view returns (taxBeneficiaryView[] memory list) {
    list = new taxBeneficiaryView[](5);

    unchecked {
      for (uint8 i = 1; i < 6; i++) { list[i - 1] = taxBeneficiaryView(_taxBeneficiary[i].account, _taxBeneficiary[i].percent, _taxBeneficiary[i].unclaimed); }
    }
  }

  /// @notice Sets a tax beneficiary
  /// @dev Maximum of 5 wallets can be assigned
  /// @param slot Slot number (1 to 5)
  /// @param account Beneficiary address
  /// @param percent[3] Index 0 is for tx tax, 1 is for buy tax, 2 is for sell tax, multiplied by denominator
  function setTaxBeneficiary(uint8 slot, address account, uint24[3] memory percent) external onlyOwner {
    require(!_renounced.Taxable);
    require(slot >= 1 && slot <= 5, "Reserved");

    _setTaxBeneficiary(slot, account, percent);
  }

  function _setTaxBeneficiary(uint8 slot, address account, uint24[3] memory percent) internal {
    require(slot <= 5);
    require(account != address(this) && account != address(0xdEaD));

    taxBeneficiary storage taxBeneficiarySlot = _taxBeneficiary[slot];

    unchecked {
      _totalTxTax += percent[0] - taxBeneficiarySlot.percent[0];
      _totalBuyTax += percent[1] - taxBeneficiarySlot.percent[1];
      _totalSellTax += percent[2] - taxBeneficiarySlot.percent[2];

      require(_totalTxTax <= 25 * _denominator && ((_totalBuyTax <= 25 * _denominator && _totalSellTax <= 25 * _denominator) && (_totalBuyTax + _totalSellTax <= 25 * _denominator)), "High Tax");
      taxBeneficiarySlot.account = account;
      taxBeneficiarySlot.percent = percent;
    }

    if (!taxBeneficiarySlot.exists) { taxBeneficiarySlot.exists = true; }

    emit SetTaxBeneficiary(slot, account, percent);
  }

  /// @notice Total amount of dividends distributed so far
  /// @dev Returns the total amount of swapped {{HRVST}}
  function totalDividendsDistributed() external view returns (uint256) {
    return _totalDividendsDistributed;
  }

  /// @notice Total amount of dividends distributed so far
  function totalDividendsDistributedPerReflectionToken() external view returns (uint256) {
    return _totalDividendsDistributedPerReflectionToken[address(_dividendToken)];
  }

  /// @notice Returns the gas limit to be used when distributing dividends
  /// @dev Only used if the token to be distributed is not the same one as this contract
  function getGasLimitForDividendDistribution() external view returns (uint256) {
    return _gasLimitForDividendDistribution;
  }

  /// @notice Sets the gas limit to be used when distributing dividends
  /// @dev Essential for distributing dividends to a large number of wallets in batches
  /// @param gas Gas limit, in Gwei
  function setGasLimitForDividendDistribution(uint256 gas) external onlyOwner {
    require(gas >= 200000);

    _gasLimitForDividendDistribution = gas;
  }

  /// @notice Triggers the tax and dividend distribution
  /// @dev Will only be executed if there is no ongoing swap or tax distribution
  function autoTaxDistribute() external onlyOwner {
    require(!_swapping && !_distributing);

    _autoTaxDistribute();
  }

  function _autoTaxDistribute() internal lockDistributing {
    if (_totalTaxUnclaimed == 0 && (_totalDividendsUnclaimed == 0 || (_minDividendDistributionPercent > 0 && _totalDividendsUnclaimed < _percentage(_totalSupply, uint256(_minDividendDistributionPercent))))) { return; }

    unchecked {
      uint256 iterations;
      uint256 distributedDividends;
      uint256 distributedTaxes;

      for (uint8 i = 1; i < 6; i++) {
        taxBeneficiary storage taxBeneficiarySlot = _taxBeneficiary[i];
        address account = taxBeneficiarySlot.account;

        if (taxBeneficiarySlot.unclaimed == 0 || account == _dex.pair) { continue; }

        uint256 unclaimed;
        uint256 _distributedTaxes;
        uint256 _distributedDividends;
        uint256 _iterations;

        if (account == address(0)) {
          unclaimed = _percentage(address(_dividendToken) == address(this) ? _amountForDividendDistribution : _amountSwappedForDividendDistribution, (100 * uint256(_denominator) * taxBeneficiarySlot.unclaimed) / _totalDividendsUnclaimed);

          uint256 idx = _lastDividendDistributionHolderIndex;
          uint256 cnt = _holders.length;
          uint256 gasLeft = gasleft();
          uint256 gasUsed;

          while (gasUsed < _gasLimitForDividendDistribution && _iterations++ < cnt) {
            if (idx >= cnt) { idx = 0; }

            address holder = _holders[idx++];

            if (holder == address(this) || holder == address(0) || holder == _dex.pair || _balance[holder] < _minDividendDistributionHolderBalance) { continue; }

            _distributedDividends += _distribute(holder, _percentage(unclaimed, (100 * uint256(_denominator) * _balance[holder]) / (_totalSupply - _balance[_dex.pair] - _balance[address(this)])), true);

            gasUsed += gasLeft - gasleft();
            gasLeft = gasleft();
          }

          _lastDividendDistributionHolderIndex = idx;

          if (_distributedDividends > 0) {
            taxBeneficiarySlot.unclaimed -= _distributedDividends;
            distributedDividends += _distributedDividends;
          }
        } else {
          unclaimed = _percentage(address(_taxToken) == address(this) ? _amountForTaxDistribution : _amountSwappedForTaxDistribution, (100 * uint256(_denominator) * taxBeneficiarySlot.unclaimed) / _totalTaxUnclaimed);

          if (unclaimed == 0) { continue; }

          _distributedTaxes = _distribute(account, unclaimed, false);

          if (_distributedTaxes > 0) {
            ++iterations;

            taxBeneficiarySlot.unclaimed -= _distributedTaxes;
            distributedTaxes += _distributedTaxes;
          }
        }

        iterations += _iterations;
      }

      _lastTaxDistribution = _timestamp();

      if (distributedTaxes > 0) {
        _totalTaxUnclaimed -= distributedTaxes;

        emit TaxDistributed(distributedTaxes);
      }

      if (distributedDividends > 0) {
        _totalDividendsUnclaimed -= distributedDividends;
        _totalDividendsDistributed += distributedDividends;

        emit DividendsDistributed(distributedDividends, iterations);
      }
    }
  }

  function _distribute(address account, uint256 unclaimed, bool isDividend) private returns (uint256) {
    if (unclaimed == 0) { return 0; }

    unchecked {
      if (address(isDividend ? _dividendToken : _taxToken) == address(this)) {
        if (_maxBalanceAmount > 0 && _balance[account] + unclaimed > _maxBalanceAmount) {
          unclaimed = _maxBalanceAmount > _balance[account] ? _maxBalanceAmount - _balance[account] : 0;

          if (unclaimed == 0) { return 0; }
        }

        super._transfer(address(this), account, unclaimed);

        if (isDividend) {
          _amountForDividendDistribution -= unclaimed;
          _holder[account].dividends[address(_dividendToken)] += unclaimed;
          _totalDividendsDistributedPerReflectionToken[address(_dividendToken)] += unclaimed;
        } else {
          _amountForTaxDistribution -= unclaimed;
        }

        if (!_holder[account].exists) {
          _holder[account].exists = true;
          _holders.push(account);
        }
      } else {
        uint256 percent = (100 * uint256(_denominator) * unclaimed) / (isDividend ? _amountSwappedForDividendDistribution : _amountSwappedForTaxDistribution);
        uint256 amount;

        if (address(isDividend ? _dividendToken : _taxToken) == _dex.WETH) {
          amount = _percentage((isDividend ? _ethForDividendDistribution : _ethForTaxDistribution), percent);

          (bool success, ) = payable(account).call{ value: amount, gas: 30000 }("");

          if (!success) { return 0; }

          if (isDividend) {
            _ethForDividendDistribution -= amount;
          } else {
            _ethForTaxDistribution -= amount;
          }
        } else {
          amount = _percentage((isDividend ? _tokensForDividendDistribution[address(_dividendToken)] : _tokensForTaxDistribution[address(_taxToken)]), percent);

          if (isDividend) {
            try _dividendToken.transfer(account, amount) { _tokensForDividendDistribution[address(_dividendToken)] -= amount; } catch { return 0; }
          } else {
            try _taxToken.transfer(account, amount) { _tokensForTaxDistribution[address(_taxToken)] -= amount; } catch { return 0; }
          }
        }

        if (isDividend) {
          _amountSwappedForDividendDistribution -= unclaimed;
          _holder[account].dividends[address(_dividendToken)] += amount;
          _totalDividendsDistributedPerReflectionToken[address(_dividendToken)] += amount;
        } else {
          _amountSwappedForTaxDistribution -= unclaimed;
        }
      }
    }

    return unclaimed;
  }

  /// @notice Suspend or reinstate tax collection
  /// @param status True to suspend, False to reinstate existent taxes
  function suspendTaxes(bool status) external onlyOwner {
    require(!_renounced.Taxable);

    _suspendTaxes = status;
  }

  /// @notice Checks if tax collection is currently suspended
  function taxesSuspended() external view returns (bool) {
    return _suspendTaxes;
  }

  /// @notice Returns the dividends received so far for a given wallet
  /// @param account Address of the wallet
  function getDividendsDistributed(address account) external view returns (uint256) {
    return _holder[account].dividends[address(_dividendToken)];
  }

  /// @notice Sets the minimum balance a holder must have to be eligible for dividend distribution
  /// @param balance Minimum amount a holder must have
  function setMinDividendDistributionHolderBalance(uint256 balance) external onlyOwner {
    require(!_renounced.Taxable);

    _minDividendDistributionHolderBalance = balance;
  }

  /// @notice Returns the min. balance a holder must have to be eligible for dividend distribution
  function getMinDividendDistributionHolderBalance() external view returns (uint256) {
    return _minDividendDistributionHolderBalance;
  }

  /// @notice Sets the min. percentage of unclaimed dividends required to proceed with distribution
  /// @param percent Minimum percentage, multiplied by denominator (0.01% to 1% of total supply, 0 to disable)
  function setMinDividendDistributionPercent(uint24 percent) external onlyOwner {
    require(!_renounced.Taxable);
    require(percent == 0 || (percent >= 10 && percent <= _denominator), "0.01% to 1%");

    _minDividendDistributionPercent = percent;
  }

  /// @notice Returns the min. percentage of unclaimed dividends required to proceed with distribution
  function getMinDividendDistributionPercent() external view returns (uint24) {
    return _minDividendDistributionPercent;
  }
}

File 10 of 12 : CF_MaxBalance.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import "./CF_Common.sol";
import "./CF_Ownable.sol";

abstract contract CF_MaxBalance is CF_Common, CF_Ownable {
  event SetMaxBalancePercent(uint24 percent);
  event RenouncedMaxBalance();

  /// @notice Permanently renounce and prevent the owner from being able to update the max. balance
  /// @dev Existing settings will continue to be effective
  function renounceMaxBalance() external onlyOwner {
    _renounced.MaxBalance = true;

    emit RenouncedMaxBalance();
  }

  /// @notice Percentage of the max. balance per wallet, depending on total supply
  function getMaxBalancePercent() external view returns (uint24) {
    return _maxBalancePercent;
  }

  /// @notice Set the max. percentage of a wallet balance, depending on total supply
  /// @param percent Desired percentage, multiplied by denominator (min. 0.1% of total supply, 0 to disable)
  function setMaxBalancePercent(uint24 percent) external onlyOwner {
    require(!_renounced.MaxBalance);

    unchecked {
      require(percent == 0 || (percent >= 100 && percent <= 100 * _denominator));
    }

    _setMaxBalancePercent(percent);

    emit SetMaxBalancePercent(percent);
  }

  function _setMaxBalancePercent(uint24 percent) internal {
    _maxBalancePercent = percent;
    _maxBalanceAmount = percent > 0 ? _percentage(_totalSupply, uint256(percent)) : 0;

    if (!_initialized) { emit SetMaxBalancePercent(percent); }
  }
}

File 11 of 12 : CF_DEXRouterV2.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import "./CF_Common.sol";
import "./CF_Ownable.sol";
import "./CF_ERC20.sol";

abstract contract CF_DEXRouterV2 is CF_Common, CF_Ownable, CF_ERC20 {
  event AddedLiquidity(uint256 tokenAmount, uint256 ethAmount, uint256 liquidity);
  event SwappedTokensForNative(uint256 tokenAmount, uint256 ethAmount);
  event SwappedTokensForTokens(address token, uint256 token0Amount, uint256 token1Amount);
  event SetDEXRouterV2(address indexed router, address indexed pair, address receiver);
  event TradingEnabled();
  event RenouncedDEXRouterV2();

  modifier lockSwapping {
    _swapping = true;
    _;
    _swapping = false;
  }

  /// @notice Permanently renounce and prevent the owner from being able to update the DEX features
  /// @dev Existing settings will continue to be effective
  function renounceDEXRouterV2() external onlyOwner {
    _renounced.DEXRouterV2 = true;

    emit RenouncedDEXRouterV2();
  }

  function _setDEXRouterV2(address router, address receiver) internal returns (address) {
    require(router != address(0));

    if (_dex.router != router) {
      IDEXRouterV2 _router = IDEXRouterV2(router);
      IDEXFactoryV2 factory = IDEXFactoryV2(_router.factory());
      address WETH = _router.WETH();
      address pair = factory.getPair(address(this), WETH);

      if (pair == address(0)) { pair = factory.createPair(address(this), WETH); }

      _dex = DEXRouterV2(router, pair, WETH, receiver);
    }

    if (receiver != _dex.receiver) { _dex.receiver = receiver; }

    emit SetDEXRouterV2(router, _dex.pair, receiver);

    return _dex.pair;
  }

  /// @notice Returns the DEX router currently in use
  function getDEXRouterV2() external view returns (address) {
    return _dex.router;
  }

  /// @notice Returns the trading pair
  function getDEXPairV2() external view returns (address) {
    return _dex.pair;
  }

  /// @notice Returns address of the LP tokens receiver
  function getLPTokensReceiver() external view returns (address) {
    return _dex.receiver;
  }

  /// @notice Checks whether the token can be traded through the assigned DEX
  function isTradingEnabled() external view returns (bool) {
    return _tradingEnabled > 0;
  }

  /// @notice Checks the status of the auto-swapping feature
  function isAutoSwapEnabled() external view returns (bool) {
    return _autoSwapEnabled;
  }

  /// @notice Returns the percentage range of the total supply over which the auto-swap will operate when accumulating taxes in the contract balance
  function getAutoSwapPercent() external view returns (uint24 min, uint24 max) {
    return (_minAutoSwapPercent, _maxAutoSwapPercent);
  }

  /// @notice Sets the percentage range of the total supply over which the auto-swap will operate when accumulating taxes in the contract balance
  /// @param min Desired min. percentage to trigger the auto-swap, multiplied by denominator (0.001% to 1% of total supply)
  /// @param max Desired max. percentage to limit the auto-swap, multiplied by denominator (0.001% to 1% of total supply)
  function setAutoSwapPercent(uint24 min, uint24 max) external onlyOwner {
    require(!_renounced.DEXRouterV2);
    require(min >= 1 && min <= 1000, "0.001% to 1%");
    require(max >= min && max <= 1000, "0.001% to 1%");

    _setAutoSwapPercent(min, max);
  }

  function _setAutoSwapPercent(uint24 min, uint24 max) internal {
    _minAutoSwapPercent = min;
    _maxAutoSwapPercent = max;
    _minAutoSwapAmount = _percentage(_totalSupply, uint256(min));
    _maxAutoSwapAmount = _percentage(_totalSupply, uint256(max));
  }

  /// @notice Enables or disables the auto-swap function
  /// @param status True to enable, False to disable
  function enableAutoSwap(bool status) external onlyOwner {
    require(!_renounced.DEXRouterV2);
    require(!status || _dex.router != address(0), "No DEX");

    _autoSwapEnabled = status;
  }

  /// @notice Swaps the assigned amount to inject liquidity and prepare collected taxes for its distribution
  /// @dev Will only be executed if there is no ongoing swap or tax distribution and the min. threshold has been reached
  function autoSwap() external {
    require(_autoSwapEnabled && !_swapping && !_distributing);

    _autoSwap(false);
  }

  /// @notice Swaps the assigned amount to inject liquidity and prepare collected taxes for its distribution
  /// @dev Will only be executed if there is no ongoing swap or tax distribution and the min. threshold has been reached unless forced
  /// @param force Ignore the min. and max. threshold amount
  function autoSwap(bool force) external onlyOwner {
    require((force || _autoSwapEnabled) && !_swapping && !_distributing);

    _autoSwap(force);
  }

  function _autoSwap(bool force) internal lockSwapping {
    if (!force && !_autoSwapEnabled) { return; }

    unchecked {
      uint256 amountForLiquidityToSwap = _amountForLiquidity > 0 ? _amountForLiquidity / 2 : 0;
      uint256 amountForTaxDistributionToSwap = (address(_taxToken) == _dex.WETH ? _amountForTaxDistribution : 0);
      uint256 amountForDividendDistributionToSwap = (address(_dividendToken) == _dex.WETH ? _amountForDividendDistribution : 0);
      uint256 amountToSwap = amountForTaxDistributionToSwap + amountForDividendDistributionToSwap + amountForLiquidityToSwap;

      if (!force && amountToSwap > _maxAutoSwapAmount) {
        amountForLiquidityToSwap = amountForLiquidityToSwap > 0 ? _percentage(_maxAutoSwapAmount, (100 * uint256(_denominator) * amountForLiquidityToSwap) / amountToSwap) : 0;
        amountForTaxDistributionToSwap = amountForTaxDistributionToSwap > 0 ? _percentage(_maxAutoSwapAmount, (100 * uint256(_denominator) * amountForTaxDistributionToSwap) / amountToSwap) : 0;
        amountForDividendDistributionToSwap = amountForDividendDistributionToSwap > 0 ? _percentage(_maxAutoSwapAmount, (100 * uint256(_denominator) * amountForDividendDistributionToSwap) / amountToSwap) : 0;
        amountToSwap = amountForTaxDistributionToSwap + amountForDividendDistributionToSwap + amountForLiquidityToSwap;
      }

      if ((force || amountToSwap >= _minAutoSwapAmount) && _balance[address(this)] >= amountToSwap + amountForLiquidityToSwap) {
        uint256 ethBalance = address(this).balance;
        address[] memory pathToSwapExactTokensForNative = new address[](2);
        pathToSwapExactTokensForNative[0] = address(this);
        pathToSwapExactTokensForNative[1] = _dex.WETH;

        _approve(address(this), _dex.router, amountToSwap);

        try IDEXRouterV2(_dex.router).swapExactTokensForETHSupportingFeeOnTransferTokens(amountToSwap, 0, pathToSwapExactTokensForNative, address(this), block.timestamp) {
          if (_amountForLiquidity > 0) { _amountForLiquidity -= amountForLiquidityToSwap; }

          uint256 ethAmount = address(this).balance - ethBalance;

          emit SwappedTokensForNative(amountToSwap, ethAmount);

          if (ethAmount > 0) {
            _ethForLiquidity += _percentage(ethAmount, (100 * uint256(_denominator) * amountForLiquidityToSwap) / amountToSwap);

            if (address(_taxToken) == _dex.WETH || address(_dividendToken) == _dex.WETH) {
              if (address(_taxToken) == _dex.WETH) {
                _ethForTaxDistribution += _percentage(ethAmount, (100 * uint256(_denominator) * amountForTaxDistributionToSwap) / amountToSwap);
                _amountSwappedForTaxDistribution += amountForTaxDistributionToSwap;
                _amountForTaxDistribution -= amountForTaxDistributionToSwap;
              }

              if (address(_dividendToken) == _dex.WETH) {
                _ethForDividendDistribution += _percentage(ethAmount, (100 * uint256(_denominator) * amountForDividendDistributionToSwap) / amountToSwap);
                _amountSwappedForDividendDistribution += amountForDividendDistributionToSwap;
                _amountForDividendDistribution -= amountForDividendDistributionToSwap;
              }
            }
          }
        } catch {
          _approve(address(this), _dex.router, 0);
        }
      }

      if (address(_taxToken) != address(this) && address(_taxToken) != _dex.WETH) {
        amountForTaxDistributionToSwap = _amountForTaxDistribution;

        if (!force && amountForTaxDistributionToSwap > _maxAutoSwapAmount) { amountForTaxDistributionToSwap = _maxAutoSwapAmount; }

        if ((force || amountForTaxDistributionToSwap >= _minAutoSwapAmount) && _balance[address(this)] >= amountForTaxDistributionToSwap) {
          uint256 tokenAmount = _swapTokensForTokens(_taxToken, amountForTaxDistributionToSwap);

          if (tokenAmount > 0) {
            _tokensForTaxDistribution[address(_taxToken)] += tokenAmount;
            _amountSwappedForTaxDistribution += amountForTaxDistributionToSwap;
            _amountForTaxDistribution -= amountForTaxDistributionToSwap;
          }
        }
      }

      if (address(_dividendToken) != address(this) && address(_dividendToken) != _dex.WETH) {
        amountForDividendDistributionToSwap = _amountForDividendDistribution;

        if (!force && amountForDividendDistributionToSwap > _maxAutoSwapAmount) { amountForDividendDistributionToSwap = _maxAutoSwapAmount; }

        if ((force || amountForDividendDistributionToSwap >= _minAutoSwapAmount) && _balance[address(this)] >= amountForDividendDistributionToSwap) {
          uint256 reflectionAmount = _swapTokensForTokens(_dividendToken, amountForDividendDistributionToSwap);

          if (reflectionAmount > 0) {
            _tokensForDividendDistribution[address(_dividendToken)] += reflectionAmount;
            _amountSwappedForDividendDistribution += amountForDividendDistributionToSwap;
            _amountForDividendDistribution -= amountForDividendDistributionToSwap;
          }
        }
      }
    }

    _addLiquidity(force);
    _lastSwap = _timestamp();
  }

  function _swapTokensForTokens(IERC20 token, uint256 amount) private returns (uint256 tokenAmount) {
    uint256 tokenBalance = token.balanceOf(address(this));
    address[] memory pathToSwapExactTokensForTokens = new address[](3);
    pathToSwapExactTokensForTokens[0] = address(this);
    pathToSwapExactTokensForTokens[1] = _dex.WETH;
    pathToSwapExactTokensForTokens[2] = address(token);

    _approve(address(this), _dex.router, amount);

    try IDEXRouterV2(_dex.router).swapExactTokensForTokensSupportingFeeOnTransferTokens(amount, 0, pathToSwapExactTokensForTokens, address(this), block.timestamp) {
      tokenAmount = token.balanceOf(address(this)) - tokenBalance;

      emit SwappedTokensForTokens(address(token), amount, tokenAmount);
    } catch {
      _approve(address(this), _dex.router, 0);
    }
  }

  function _addLiquidity(bool force) private {
    if (!force && (_amountForLiquidity < _minAutoAddLiquidityAmount || _ethForLiquidity == 0)) { return; }

    unchecked {
      uint256 amountForLiquidityToAdd = !force && _amountForLiquidity > _maxAutoAddLiquidityAmount ? _maxAutoAddLiquidityAmount : _amountForLiquidity;
      uint256 ethForLiquidityToAdd = !force && _amountForLiquidity > _maxAutoAddLiquidityAmount ? _percentage(_ethForLiquidity, 100 * uint256(_denominator) * (_maxAutoAddLiquidityAmount / _amountForLiquidity)) : _ethForLiquidity;

      _approve(address(this), _dex.router, amountForLiquidityToAdd);

      try IDEXRouterV2(_dex.router).addLiquidityETH{ value: ethForLiquidityToAdd }(address(this), amountForLiquidityToAdd, 0, 0, _dex.receiver, block.timestamp) returns (uint256 amountToken, uint256 amountETH, uint256 liquidity) {
        emit AddedLiquidity(amountToken, amountETH, liquidity);

        _amountForLiquidity -= amountForLiquidityToAdd;
        _ethForLiquidity -= ethForLiquidityToAdd;
      } catch {
        _approve(address(this), _dex.router, 0);
      }
    }
  }

  /// @notice Returns the percentage range of the total supply over which the auto add liquidity will operate when accumulating taxes in the contract balance
  /// @dev Applies only if a Tax Beneficiary is the liquidity pool
  function getAutoAddLiquidityPercent() external view returns (uint24 min, uint24 max) {
    return (_minAutoAddLiquidityPercent, _maxAutoAddLiquidityPercent);
  }

  /// @notice Sets the percentage range of the total supply over which the auto add liquidity will operate when accumulating taxes in the contract balance
  /// @param min Desired min. percentage to trigger the auto add liquidity, multiplied by denominator (0.01% to 100% of total supply)
  /// @param max Desired max. percentage to limit the auto add liquidity, multiplied by denominator (0.01% to 100% of total supply)
  function setAutoAddLiquidityPercent(uint24 min, uint24 max) external onlyOwner {
    require(!_renounced.DEXRouterV2);
    require(min >= 10 && min <= 100 * _denominator, "0.01% to 100%");
    require(max >= min && max <= 100 * _denominator, "0.01% to 100%");

    _setAutoAddLiquidityPercent(min, max);
  }

  function _setAutoAddLiquidityPercent(uint24 min, uint24 max) internal {
    _minAutoAddLiquidityPercent = min;
    _maxAutoAddLiquidityPercent = max;
    _minAutoAddLiquidityAmount = _percentage(_totalSupply, uint256(min));
    _maxAutoAddLiquidityAmount = _percentage(_totalSupply, uint256(max));
  }

  /// @notice Returns the token for tax distribution
  function getTaxToken() external view returns (address) {
    return address(_taxToken);
  }

  function _setTaxToken(address token) internal {
    require((!_initialized && token == address(0)) || token == address(this) || token == _dex.WETH || IDEXFactoryV2(IDEXRouterV2(_dex.router).factory()).getPair(_dex.WETH, token) != address(0), "No Pair");

    _taxToken = IERC20(token == address(0) ? address(this) : token);
  }

  /// @notice Returns the reflection token for dividend distribution
  function getDividendReflection() external view returns (address) {
    return address(_dividendToken);
  }

  function _setDividendReflection(address token) internal {
    require((!_initialized && token == address(0)) || token == address(this) || token == _dex.WETH || IDEXFactoryV2(IDEXRouterV2(_dex.router).factory()).getPair(_dex.WETH, token) != address(0), "No Pair");

    _dividendToken = IERC20(token == address(0) ? address(this) : token);
  }

  /// @notice Enables the trading capability via the DEX set up
  /// @dev Once enabled, it cannot be reverted
  function enableTrading() external onlyOwner {
    require(!_renounced.DEXRouterV2);
    require(_tradingEnabled == 0, "Already enabled");

    _tradingEnabled = _timestamp();

    emit TradingEnabled();
  }
}

File 12 of 12 : CF_Recoverable.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import "./CF_Common.sol";
import "./CF_Ownable.sol";

abstract contract CF_Recoverable is CF_Common, CF_Ownable {
  /// @notice Recovers a misplaced amount of an ERC-20 token sitting in the contract balance
  /// @dev Beware of scam tokens!
  /// @dev Note that if the token of this contract is specified, amounts allocated for tax distribution, dividends and liquidity are reserved
  /// @param token Address of the ERC-20 token
  /// @param to Recipient
  /// @param amount Amount to be transferred
  function recoverERC20(address token, address to, uint256 amount) external onlyOwner {
    unchecked {
      uint256 balance = IERC20(token).balanceOf(address(this));
      uint256 allocated = token == address(this) ? _amountForTaxDistribution + _amountForDividendDistribution + _amountForLiquidity : (address(_taxToken) == token ? _tokensForTaxDistribution[address(_taxToken)] : 0) + (address(_dividendToken) == token ? _tokensForDividendDistribution[address(_dividendToken)] : 0);

      require(balance - (allocated >= balance ? balance : allocated) >= amount, "Exceeds balance");
    }

    IERC20(token).transfer(to, amount);
  }

  /// @notice Recovers a misplaced ERC-721 (NFT) sitting in the contract
  /// @dev Beware of scam tokens!
  /// @param token Address of the ERC-721 token
  /// @param to Recipient
  /// @param tokenId Unique identifier of the NFT
  function recoverERC721(address token, address to, uint256 tokenId) external onlyOwner {
    IERC721(token).safeTransferFrom(address(this), to, tokenId);
  }

  /// @notice Recovers a misplaced amount of native tokens sitting in the contract balance
  /// @dev Note that if the reflection token is the wrapped native, amounts allocated for tax distribution, dividends and/or liquidity are reserved
  /// @param to Recipient
  /// @param amount Amount of native tokens to be transferred
  function recoverNative(address payable to, uint256 amount) external onlyOwner {
    unchecked {
      uint256 balance = address(this).balance;
      uint256 allocated = (address(_taxToken) == _dex.WETH ? _ethForTaxDistribution : 0) + (address(_dividendToken) == _dex.WETH ? _ethForDividendDistribution : 0);

      require(balance - (allocated >= balance ? balance : allocated) >= amount, "Exceeds balance");
    }

    (bool success, ) = to.call{ value: amount }("");

    require(success);
  }
}

Settings
{
  "optimizer": {
    "runs": 200,
    "enabled": true
  },
  "evmVersion": "cancun",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidity","type":"uint256"}],"name":"AddedLiquidity","type":"event"},{"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":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"iterations","type":"uint256"}],"name":"DividendsDistributed","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":[],"name":"RenouncedDEXRouterV2","type":"event"},{"anonymous":false,"inputs":[],"name":"RenouncedMaxBalance","type":"event"},{"anonymous":false,"inputs":[],"name":"RenouncedMaxTx","type":"event"},{"anonymous":false,"inputs":[],"name":"RenouncedTaxable","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"router","type":"address"},{"indexed":true,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"}],"name":"SetDEXRouterV2","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint24","name":"percent","type":"uint24"}],"name":"SetMaxBalancePercent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint24","name":"percent","type":"uint24"}],"name":"SetMaxTxPercent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"slot","type":"uint8"},{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint24[3]","name":"percent","type":"uint24[3]"}],"name":"SetTaxBeneficiary","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"}],"name":"SwappedTokensForNative","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"token0Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"token1Amount","type":"uint256"}],"name":"SwappedTokensForTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TaxDistributed","type":"event"},{"anonymous":false,"inputs":[],"name":"TradingEnabled","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"},{"stateMutability":"payable","type":"fallback"},{"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":[],"name":"autoSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"force","type":"bool"}],"name":"autoSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"autoTaxDistribute","outputs":[],"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":"buyTax","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"}],"name":"buyTax","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"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":"denominator","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"}],"name":"enableAutoSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAutoAddLiquidityPercent","outputs":[{"internalType":"uint24","name":"min","type":"uint24"},{"internalType":"uint24","name":"max","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAutoSwapPercent","outputs":[{"internalType":"uint24","name":"min","type":"uint24"},{"internalType":"uint24","name":"max","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDEXPairV2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDEXRouterV2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDividendReflection","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getDividendsDistributed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGasLimitForDividendDistribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLPTokensReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxBalancePercent","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxTxPercent","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinDividendDistributionHolderBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinDividendDistributionPercent","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTaxToken","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[],"name":"info","outputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"string","name":"version","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isAutoSwapEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isTradingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"listTaxBeneficiaries","outputs":[{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint24[3]","name":"percent","type":"uint24[3]"},{"internalType":"uint256","name":"unclaimed","type":"uint256"}],"internalType":"struct CF_Taxable.taxBeneficiaryView[]","name":"list","type":"tuple[]"}],"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":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"recoverERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverNative","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceDEXRouterV2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceMaxBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceMaxTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceTaxable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounced","outputs":[{"internalType":"bool","name":"MaxTx","type":"bool"},{"internalType":"bool","name":"MaxBalance","type":"bool"},{"internalType":"bool","name":"DEXRouterV2","type":"bool"},{"internalType":"bool","name":"Taxable","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"sellTax","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellTax","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint24","name":"min","type":"uint24"},{"internalType":"uint24","name":"max","type":"uint24"}],"name":"setAutoAddLiquidityPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"min","type":"uint24"},{"internalType":"uint24","name":"max","type":"uint24"}],"name":"setAutoSwapPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"gas","type":"uint256"}],"name":"setGasLimitForDividendDistribution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"percent","type":"uint24"}],"name":"setMaxBalancePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"percent","type":"uint24"}],"name":"setMaxTxPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"name":"setMinDividendDistributionHolderBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"percent","type":"uint24"}],"name":"setMinDividendDistributionPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"slot","type":"uint8"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint24[3]","name":"percent","type":"uint24[3]"}],"name":"setTaxBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"}],"name":"suspendTaxes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxesSuspended","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDividendsDistributed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDividendsDistributedPerReflectionToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTaxCollected","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","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":[],"name":"txTax","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"}],"name":"txTax","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c060405234801562000010575f80fd5b5060408051808201909152601081526f12185c9d995cdd08141c9bdd1bd8dbdb60821b602082015260289062000047908262000f1e565b5060408051808201909152600581526412149594d560da1b602082015260299062000073908262000f1e565b50601260a0526b033b2e3c9fd0803ce8000000600a55305f818152600260205260408120805460ff191660019081179091556007805491820181559091525f80516020620054158339815191520180546001600160a01b0319169091179055620000f173267f44da6305c82f47b5adb1af35860bdb3f1c86620002a0565b6200011473267f44da6305c82f47b5adb1af35860bdb3f1c86620186a0620002f1565b6200014873a5e0829caced8ffdd4de3c43696c57f7d7a678ff73267f44da6305c82f47b5adb1af35860bdb3f1c86620003ae565b5062000168730d500b1d8e8ef31e21c99d1db9a6444d3adf12706200069f565b62000187730d500b1d8e8ef31e21c99d1db9a6444d3adf127062000854565b6008805460ff65ffffffffffff60b01b0119167a012c00006400000000000000000000000000000000000000000001179055600a54620186a060648202819004600d5561012c90910204600e55620001e46064620186a062000a05565b670de0b6b3a76400006018556008805462ffffff60981b19166019609a1b179055620493e0601755604080516060810182525f81526107d060208201819052918101919091526200024e9060019073372a75d1e50d6d3c25810328d010fda2d284264c9062000a67565b604080516060810182525f80825261177060208301819052928201929092526200027b9160029162000a67565b620002886103e862000cb3565b620002956103e862000d3c565b60016080526200106e565b602780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b60805115620002fe575f80fd5b5f62000318600a548362ffffff1662000dc160201b60201c565b6001600160a01b0384165f8181526020818152604080832085905560028252808320805460ff1916600190811790915560078054918201815584525f80516020620054158339815191520180546001600160a01b0319168517905551848152939450919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b5f6001600160a01b038316620003c2575f80fd5b6023546001600160a01b0384811691161462000613575f8390505f816001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200041a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000440919062000fea565b90505f826001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000480573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620004a6919062000fea565b60405163e6a4390560e01b81523060048201526001600160a01b0380831660248301529192505f9184169063e6a43905906044016020604051808303815f875af1158015620004f7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200051d919062000fea565b90506001600160a01b038116620005a3576040516364e329cb60e11b81523060048201526001600160a01b03838116602483015284169063c9c65396906044016020604051808303815f875af11580156200057a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620005a0919062000fea565b90505b604080516080810182526001600160a01b03808a168083529381166020830181905294811692820183905288166060909101819052602380546001600160a01b03199081169094179055602480548416909417909355602580548316909117905560268054909116909117905550505b6026546001600160a01b038381169116146200064557602680546001600160a01b0319166001600160a01b0384161790555b6024546040516001600160a01b038481168252918216918516907fd0cdc441c8110da5df2f4a64e1cee8a6794d8016c982757bb5d8971cde6b6bf39060200160405180910390a3506024546001600160a01b031692915050565b608051158015620006b757506001600160a01b038116155b80620006cb57506001600160a01b03811630145b80620006e457506025546001600160a01b038281169116145b80620007dc57506023546040805163c45a015560e01b815290515f926001600160a01b03169163c45a01559160048083019260209291908290030181865afa15801562000733573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000759919062000fea565b60255460405163e6a4390560e01b81526001600160a01b039182166004820152848216602482015291169063e6a43905906044016020604051808303815f875af1158015620007aa573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620007d0919062000fea565b6001600160a01b031614155b620008185760405162461bcd60e51b81526020600482015260076024820152662737902830b4b960c91b60448201526064015b60405180910390fd5b6001600160a01b038116156200082f578062000831565b305b602180546001600160a01b0319166001600160a01b039290921691909117905550565b6080511580156200086c57506001600160a01b038116155b806200088057506001600160a01b03811630145b806200089957506025546001600160a01b038281169116145b806200099157506023546040805163c45a015560e01b815290515f926001600160a01b03169163c45a01559160048083019260209291908290030181865afa158015620008e8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200090e919062000fea565b60255460405163e6a4390560e01b81526001600160a01b039182166004820152848216602482015291169063e6a43905906044016020604051808303815f875af11580156200095f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000985919062000fea565b6001600160a01b031614155b620009c95760405162461bcd60e51b81526020600482015260076024820152662737902830b4b960c91b60448201526064016200080f565b6001600160a01b03811615620009e05780620009e2565b305b602280546001600160a01b0319166001600160a01b039290921691909117905550565b6008805462ffffff60e01b1916600160e01b62ffffff858116918202929092179092556009805462ffffff1916918416919091179055600a5462000a4d91620186a091020490565b600f55600a54620186a062ffffff92909216020460105550565b60058360ff16111562000a78575f80fd5b6001600160a01b038216301480159062000a9d57506001600160a01b03821661dead14155b62000aa6575f80fd5b60ff83165f9081526003602090815260409182902060018101805485516008805462ffffff60501b19811662ffffff9485169093036a0100000000000000000000808304861691909101851681029384178084558654988b015162ffffff60681b1990951665ffffffffffff60501b199093169290921763010000009098048516909303600160681b9182900485160184160295909517808655925495870151600160801b80850484166601000000000000909804841690910396909601821690950262ffffff60801b19909216919091179283905590926161a89204161180159062000bf157506008546161a8600160681b90910462ffffff161180159062000bc157506008546161a8600160801b90910462ffffff1611155b801562000bf157506008546161a8600160681b820462ffffff908116600160801b90930481169290920190911611155b62000c2a5760405162461bcd60e51b8152602060048201526008602482015267090d2ced040a8c2f60c31b60448201526064016200080f565b8054610100600160a81b0319166101006001600160a01b0385160217815562000c596001820183600362000dcb565b50805460ff1662000c7057805460ff191660011781555b7f93dd041a76c0a756b346cffaf7b1e0b1c3f26f0c908f8a4600c5e9d530fa21a184848460405162000ca59392919062001019565b60405180910390a150505050565b6008805462ffffff60201b191664010000000062ffffff84169081029190911790915562000ce2575f62000cf4565b600a54620186a062ffffff8316909102045b600b5560805162000d395760405162ffffff821681527ff01936354f43c5b49521c6c3fdc9740709976ee07acac3ebf79fbd6282cda195906020015b60405180910390a15b50565b6008805462ffffff60381b191667010000000000000062ffffff84169081029190911790915562000d6e575f62000d80565b600a54620186a062ffffff8316909102045b600c5560805162000d395760405162ffffff821681527fd03edfeea801807308f0e9302e347c8a12ad32508cae5bce26e9e2a3654158c99060200162000d30565b620186a091020490565b60018301918390821562000e58579160200282015f5b8382111562000e2557835183826101000a81548162ffffff021916908362ffffff160217905550926020019260030160208160020104928301926001030262000de1565b801562000e565782816101000a81549062ffffff021916905560030160208160020104928301926001030262000e25565b505b5062000e6692915062000e6a565b5090565b5b8082111562000e66575f815560010162000e6b565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168062000ea957607f821691505b60208210810362000ec857634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000f1957805f5260205f20601f840160051c8101602085101562000ef55750805b601f840160051c820191505b8181101562000f16575f815560010162000f01565b50505b505050565b81516001600160401b0381111562000f3a5762000f3a62000e80565b62000f528162000f4b845462000e94565b8462000ece565b602080601f83116001811462000f88575f841562000f705750858301515b5f19600386901b1c1916600185901b17855562000fe2565b5f85815260208120601f198616915b8281101562000fb85788860151825594840194600190910190840162000f97565b508582101562000fd657878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b5f6020828403121562000ffb575f80fd5b81516001600160a01b038116811462001012575f80fd5b9392505050565b60ff841681526001600160a01b03831660208083019190915260a082019060408301845f5b60038110156200106257815162ffffff16835291830191908301906001016200103e565b50505050949350505050565b60805160a0516143776200109e5f395f81816105a10152610f9001525f8181612592015261327b01526143775ff3fe6080604052600436106103a1575f3560e01c80638324c3b9116101e4578063c29215831161010b578063d8454a82116100a4578063f2cda82e11610076578063f2cda82e14610b43578063f2fde38b14610b62578063f7c3b38f14610b81578063f7de0e5714610ba2578063f868302414610bbf57005b8063d8454a8214610add578063da88d01a14610af1578063dd62ed3e14610b10578063e92871f614610b2f57005b8063ceedfa50116100dd578063ceedfa5014610a27578063d232c22014610a47578063d551160914610a9f578063d6a018eb14610abe57005b8063c2921583146109ce578063c77e006d146109eb578063c78fe0d4146109ff578063cc1776d314610a1357005b806396ce07951161017d578063a4d8971a1161014f578063a4d8971a14610954578063a5596b4f14610973578063a9059cbb14610992578063b81a0145146109b157005b806396ce0795146108e657806397a26b9e146108fa5780639c5ef8d714610921578063a457c2d71461093557005b80638d8350ca116101b65780638d8350ca146108775780638da5cb5b1461089657806395101f90146108b357806395d89b41146108d257005b80638324c3b91461082757806385a6b3ae1461083b5780638a8c523c1461084f5780638bf1acff1461086357005b806337061ab2116102c85780635f6417581161026157806370b749d51161023357806370b749d5146107cb578063715018a6146107df57806375de1496146107f3578063770048511461081357005b80635f641758146107385780636b979993146107575780636f05be971461077657806370a082311461079757005b80634b7d9db41161029a5780634b7d9db4146106af5780634f7041a5146106c657806354fd4d50146106ee5780635a0d4f881461071b57005b806337061ab21461063357806339509351146106525780633ed8a1691461067157806344b691ff1461069057005b806318160ddd1161033a5780632cdf2c351161030c5780632cdf2c351461056f578063313ce5671461058e57806332acf3de146105cb578063370158ea1461060d57005b806318160ddd146104ec578063211600e31461050057806323b872dd146105315780632623e9751461055057005b8063095ea7b311610373578063095ea7b31461043a5780630fcb2fe7146104595780631171bda914610484578063150bf8ab146104a357005b8063064a59d0146103aa57806306fdde03146103de578063070d8ba7146103ff57806307e9652c1461041d57005b366103a857005b005b3480156103b5575f80fd5b50600954600160381b900463ffffffff1615155b60405190151581526020015b60405180910390f35b3480156103e9575f80fd5b506103f2610bde565b6040516103d59190613e1a565b34801561040a575f80fd5b506017545b6040519081526020016103d5565b348015610428575f80fd5b5060085462010000900460ff166103c9565b348015610445575f80fd5b506103c9610454366004613e40565b610c6e565b348015610464575f80fd5b506022546001600160a01b03165f9081526004602052604090205461040f565b34801561048f575f80fd5b506103a861049e366004613e6a565b610c84565b3480156104ae575f80fd5b5061040f6104bd366004613ea8565b6001600160a01b039081165f908152600260209081526040808320602254909416835260019093019052205490565b3480156104f7575f80fd5b50600a5461040f565b34801561050b575f80fd5b506022546001600160a01b03165b6040516001600160a01b0390911681526020016103d5565b34801561053c575f80fd5b506103c961054b366004613e6a565b610e5c565b34801561055b575f80fd5b506103a861056a366004613ed0565b610e7e565b34801561057a575f80fd5b506103a8610589366004613e6a565b610f1d565b348015610599575f80fd5b5060405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016103d5565b3480156105d6575f80fd5b5060085462ffffff600160b01b8204811691600160c81b9004165b6040805162ffffff9384168152929091166020830152016103d5565b348015610618575f80fd5b50610621610f82565b6040516103d596959493929190613eeb565b34801561063e575f80fd5b506103a861064d366004613f4f565b61110d565b34801561065d575f80fd5b506103c961066c366004613e40565b61114b565b34801561067c575f80fd5b506103a861068b366004613f7d565b611162565b34801561069b575f80fd5b506103a86106aa366004613f96565b611218565b3480156106ba575f80fd5b5060085460ff166103c9565b3480156106d1575f80fd5b506106da611364565b60405162ffffff90911681526020016103d5565b3480156106f9575f80fd5b50604080518082019091526005815264189718171960d91b60208201526103f2565b348015610726575f80fd5b506021546001600160a01b0316610519565b348015610743575f80fd5b506106da610752366004613ea8565b611373565b348015610762575f80fd5b506103a8610771366004613f4f565b611400565b348015610781575f80fd5b5061078a611444565b6040516103d59190613fee565b3480156107a2575f80fd5b5061040f6107b1366004613ea8565b6001600160a01b03165f9081526020819052604090205490565b3480156107d6575f80fd5b5060185461040f565b3480156107ea575f80fd5b506103a8611569565b3480156107fe575f80fd5b50600854600160381b900462ffffff166106da565b34801561081e575f80fd5b506103a86115b1565b348015610832575f80fd5b506103a86115f2565b348015610846575f80fd5b5060155461040f565b34801561085a575f80fd5b506103a8611657565b34801561086e575f80fd5b506106da611732565b348015610882575f80fd5b506106da610891366004613ea8565b611738565b3480156108a1575f80fd5b506027546001600160a01b0316610519565b3480156108be575f80fd5b506106da6108cd366004613ea8565b611775565b3480156108dd575f80fd5b506103f26117cb565b3480156108f1575f80fd5b506103e86106da565b348015610905575f80fd5b5060085460095462ffffff600160e01b909204821691166105f1565b34801561092c575f80fd5b506103a86117da565b348015610940575f80fd5b506103c961094f366004613e40565b611836565b34801561095f575f80fd5b506103a861096e366004613ed0565b611896565b34801561097e575f80fd5b506103a861098d366004613ed0565b61190c565b34801561099d575f80fd5b506103c96109ac366004613e40565b611967565b3480156109bc575f80fd5b506026546001600160a01b0316610519565b3480156109d9575f80fd5b506024546001600160a01b0316610519565b3480156109f6575f80fd5b506103a8611973565b348015610a0a575f80fd5b506103a86119d6565b348015610a1e575f80fd5b506106da611a3d565b348015610a32575f80fd5b50600854600160981b900462ffffff166106da565b348015610a52575f80fd5b5060205460ff8082169161010081048216916301000000820481169162010000900416604080519415158552921515602085015290151591830191909152151560608201526080016103d5565b348015610aaa575f80fd5b506103a8610ab936600461406d565b611a47565b348015610ac9575f80fd5b506103a8610ad8366004613f96565b611ae5565b348015610ae8575f80fd5b5060135461040f565b348015610afc575f80fd5b506103a8610b0b366004613f7d565b611c03565b348015610b1b575f80fd5b5061040f610b2a366004614119565b611cad565b348015610b3a575f80fd5b506103a8611cd7565b348015610b4e575f80fd5b506103a8610b5d366004613e40565b611d38565b348015610b6d575f80fd5b506103a8610b7c366004613ea8565b611e3b565b348015610b8c575f80fd5b50600854640100000000900462ffffff166106da565b348015610bad575f80fd5b506023546001600160a01b0316610519565b348015610bca575f80fd5b506103a8610bd9366004613f7d565b611e80565b606060288054610bed90614150565b80601f0160208091040260200160405190810160405280929190818152602001828054610c1990614150565b8015610c645780601f10610c3b57610100808354040283529160200191610c64565b820191905f5260205f20905b815481529060010190602001808311610c4757829003601f168201915b5050505050905090565b5f610c7a338484611f47565b5060015b92915050565b6027546001600160a01b03163314610cb75760405162461bcd60e51b8152600401610cae90614188565b60405180910390fd5b6040516370a0823160e01b81523060048201525f906001600160a01b038516906370a0823190602401602060405180830381865afa158015610cfb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d1f91906141ae565b90505f6001600160a01b0385163014610da4576022546001600160a01b03868116911614610d4d575f610d68565b6022546001600160a01b03165f908152600560205260409020545b6021546001600160a01b03878116911614610d83575f610d9e565b6021546001600160a01b03165f908152600660205260409020545b01610db0565b601154601b54601a5401015b90508282821015610dc15781610dc3565b825b83031015610de35760405162461bcd60e51b8152600401610cae906141c5565b505060405163a9059cbb60e01b81526001600160a01b0383811660048301526024820183905284169063a9059cbb906044015b6020604051808303815f875af1158015610e32573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e5691906141ee565b50505050565b5f610e68843384611fa8565b610e7384848461200b565b5060015b9392505050565b6027546001600160a01b03163314610ea85760405162461bcd60e51b8152600401610cae90614188565b6020546301000000900460ff1615610ebe575f80fd5b801580610ed557506023546001600160a01b031615155b610f0a5760405162461bcd60e51b815260206004820152600660248201526509cde40888ab60d31b6044820152606401610cae565b6008805460ff1916911515919091179055565b6027546001600160a01b03163314610f475760405162461bcd60e51b8152600401610cae90614188565b604051632142170760e11b81523060048201526001600160a01b038381166024830152604482018390528416906342842e0e90606401610e16565b6060805f805f6060602860297f000000000000000000000000000000000000000000000000000000000000000060275f9054906101000a90046001600160a01b0316600a5460405180604001604052806005815260200164189718171960d91b815250858054610ff190614150565b80601f016020809104026020016040519081016040528092919081815260200182805461101d90614150565b80156110685780601f1061103f57610100808354040283529160200191611068565b820191905f5260205f20905b81548152906001019060200180831161104b57829003601f168201915b5050505050955084805461107b90614150565b80601f01602080910402602001604051908101604052809291908181526020018280546110a790614150565b80156110f25780601f106110c9576101008083540402835291602001916110f2565b820191905f5260205f20905b8154815290600101906020018083116110d557829003601f168201915b50505050509450955095509550955095509550909192939495565b6027546001600160a01b031633146111375760405162461bcd60e51b8152600401610cae90614188565b62030d40811015611146575f80fd5b601755565b5f610c7a33848461115c3388611cad565b01611f47565b6027546001600160a01b0316331461118c5760405162461bcd60e51b8152600401610cae90614188565b602054610100900460ff16156111a0575f80fd5b62ffffff811615806111cb575060648162ffffff16101580156111cb5750620186a062ffffff821611155b6111d3575f80fd5b6111dc81612547565b60405162ffffff821681527fd03edfeea801807308f0e9302e347c8a12ad32508cae5bce26e9e2a3654158c9906020015b60405180910390a150565b6027546001600160a01b031633146112425760405162461bcd60e51b8152600401610cae90614188565b6020546301000000900460ff1615611258575f80fd5b60018262ffffff161015801561127557506103e88262ffffff1611155b6112b05760405162461bcd60e51b815260206004820152600c60248201526b302e3030312520746f20312560a01b6044820152606401610cae565b8162ffffff168162ffffff16101580156112d157506103e88162ffffff1611155b61130c5760405162461bcd60e51b815260206004820152600c60248201526b302e3030312520746f20312560a01b6044820152606401610cae565b6008805465ffffffffffff60b01b1916600160b01b62ffffff80861691820262ffffff60c81b191692909217600160c81b92851692830217909255600a54620186a0928102839004600d550204600e555050565b5050565b5f61136e33611775565b905090565b6008545f9062010000900460ff161561138d57505f919050565b6001600160a01b0382163014806113b157506027546001600160a01b038381169116145b806113c957506024546001600160a01b038381169116145b806113e157506023546001600160a01b038381169116145b6113f957600854600160801b900462ffffff16610c7e565b5f92915050565b6027546001600160a01b0316331461142a5760405162461bcd60e51b8152600401610cae90614188565b60205462010000900460ff161561143f575f80fd5b601855565b60408051600580825260c08201909252606091816020015b611464613ce3565b81526020019060019003908161145c57905050905060015b60068160ff16101561156557604080516060808201835260ff84165f81815260036020818152868320805461010090046001600160a01b0316875293835281815286519485019687905294959486019460019093019290918390855b82829054906101000a900462ffffff1662ffffff16815260200190600301906020826002010492830192600103820291508084116114d85790505050505050815260200160035f8460ff1660ff1681526020019081526020015f2060020154815250826001830360ff168151811061155257611552614209565b602090810291909101015260010161147c565b5090565b6027546001600160a01b031633146115935760405162461bcd60e51b8152600401610cae90614188565b6020805463ffffffff191663010101011790556115af5f6125ea565b565b60085460ff1680156115cb5750600854610100900460ff16155b80156115e157506008546301000000900460ff16155b6115e9575f80fd5b6115af5f61263b565b6027546001600160a01b0316331461161c5760405162461bcd60e51b8152600401610cae90614188565b6020805462ff00001916620100001790556040517fb18b29d65a3b95dc80df0b9528f12b8592bd02395ca19228958e8b7cdf3ddd2b905f90a1565b6027546001600160a01b031633146116815760405162461bcd60e51b8152600401610cae90614188565b6020546301000000900460ff1615611697575f80fd5b600954600160381b900463ffffffff16156116e65760405162461bcd60e51b815260206004820152600f60248201526e105b1c9958591e48195b98589b1959608a1b6044820152606401610cae565b600980546affffffff000000000000001916600160381b63ffffffff4216021790556040517f799663458a5ef2936f7fa0c99b3336c69c25890f82974f04e811e5bb359186c7905f90a1565b5f61136e335b5f6001600160a01b03821630148061175d57506024546001600160a01b038381169116145b6113f957600854600160501b900462ffffff16610c7e565b6008545f9062010000900460ff161561178f57505f919050565b6001600160a01b0382163014806117b357506024546001600160a01b038381169116145b6113f957600854600160681b900462ffffff16610c7e565b606060298054610bed90614150565b6027546001600160a01b031633146118045760405162461bcd60e51b8152600401610cae90614188565b600854610100900460ff1615801561182657506008546301000000900460ff16155b61182e575f80fd5b6115af612bda565b5f806118423385611cad565b9050828110156118895760405162461bcd60e51b81526020600482015260126024820152714e6567617469766520616c6c6f77616e636560701b6044820152606401610cae565b610e733385858403611f47565b6027546001600160a01b031633146118c05760405162461bcd60e51b8152600401610cae90614188565b80806118ce575060085460ff165b80156118e25750600854610100900460ff16155b80156118f857506008546301000000900460ff16155b611900575f80fd5b6119098161263b565b50565b6027546001600160a01b031633146119365760405162461bcd60e51b8152600401610cae90614188565b60205462010000900460ff161561194b575f80fd5b60088054911515620100000262ff000019909216919091179055565b5f610c7a33848461200b565b6027546001600160a01b0316331461199d5760405162461bcd60e51b8152600401610cae90614188565b6020805461ff0019166101001790556040517f6754c879eecdc6d0fbd95c51f8e377373a9f6be654462f792774fe3740e317ee905f90a1565b6027546001600160a01b03163314611a005760405162461bcd60e51b8152600401610cae90614188565b6020805463ff000000191663010000001790556040517ff7f7205ed48f7a35df9b5857667bdee0189d5d7cd80588f217a82641c3b4d08c905f90a1565b5f61136e33611373565b6027546001600160a01b03163314611a715760405162461bcd60e51b8152600401610cae90614188565b60205462010000900460ff1615611a86575f80fd5b60018360ff1610158015611a9e575060058360ff1611155b611ad55760405162461bcd60e51b815260206004820152600860248201526714995cd95c9d995960c21b6044820152606401610cae565b611ae0838383612f99565b505050565b6027546001600160a01b03163314611b0f5760405162461bcd60e51b8152600401610cae90614188565b6020546301000000900460ff1615611b25575f80fd5b600a8262ffffff1610158015611b515750611b436103e86064614231565b62ffffff168262ffffff1611155b611b8d5760405162461bcd60e51b815260206004820152600d60248201526c302e30312520746f203130302560981b6044820152606401610cae565b8162ffffff168162ffffff1610158015611bbd5750611baf6103e86064614231565b62ffffff168162ffffff1611155b611bf95760405162461bcd60e51b815260206004820152600d60248201526c302e30312520746f203130302560981b6044820152606401610cae565b61136082826131d1565b6027546001600160a01b03163314611c2d5760405162461bcd60e51b8152600401610cae90614188565b60205460ff1615611c3c575f80fd5b62ffffff81161580611c67575060648162ffffff1610158015611c675750620186a062ffffff821611155b611c6f575f80fd5b611c7881613232565b60405162ffffff821681527ff01936354f43c5b49521c6c3fdc9740709976ee07acac3ebf79fbd6282cda1959060200161120d565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6027546001600160a01b03163314611d015760405162461bcd60e51b8152600401610cae90614188565b6020805460ff191660011790556040517fcc2f10fb1214ece03bcb178c4d75943daee74aff93182bfb58ba9b8ef5d8c5aa905f90a1565b6027546001600160a01b03163314611d625760405162461bcd60e51b8152600401610cae90614188565b60255460225447915f916001600160a01b03908116911614611d84575f611d88565b601f545b6025546021546001600160a01b03908116911614611da6575f611daa565b601e545b0190508282821015611dbc5781611dbe565b825b83031015611dde5760405162461bcd60e51b8152600401610cae906141c5565b50505f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114611e29576040519150601f19603f3d011682016040523d82523d5f602084013e611e2e565b606091505b5050905080611ae0575f80fd5b6027546001600160a01b03163314611e655760405162461bcd60e51b8152600401610cae90614188565b6001600160a01b038116611e77575f80fd5b611909816125ea565b6027546001600160a01b03163314611eaa5760405162461bcd60e51b8152600401610cae90614188565b60205462010000900460ff1615611ebf575f80fd5b62ffffff81161580611ee95750600a8162ffffff1610158015611ee957506103e862ffffff821611155b611f235760405162461bcd60e51b815260206004820152600b60248201526a302e30312520746f20312560a81b6044820152606401610cae565b6008805462ffffff909216600160981b0262ffffff60981b19909216919091179055565b6001600160a01b038381165f8181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b5f611fb38484611cad565b905081811015611ffe5760405162461bcd60e51b8152602060048201526016602482015275496e73756666696369656e7420616c6c6f77616e636560501b6044820152606401610cae565b610e568484848403611f47565b6008546301000000900460ff1615801561202d5750600854610100900460ff16155b801561206057506024546001600160a01b0384811691161480159061206057506023546001600160a01b03848116911614155b156120765761206e5f61263b565b612076612bda565b5f8111801561209357506027546001600160a01b03848116911614155b80156120ad57506027546001600160a01b03838116911614155b80156120c257506001600160a01b0383163014155b80156120d757506001600160a01b0382163014155b80156120f157506023546001600160a01b03838116911614155b156124a9576024546001600160a01b0384811691161480159061212257506024546001600160a01b03838116911614155b8061216b57506024546001600160a01b038481169116148061215157506024546001600160a01b038381169116145b801561216b5750600954600160381b900463ffffffff1615155b6121aa5760405162461bcd60e51b815260206004820152601060248201526f151c98591a5b99c8191a5cd8589b195960821b6044820152606401610cae565b600b5415806121bb5750600b548111155b6121f75760405162461bcd60e51b815260206004820152600d60248201526c08af0c6cacac8e640dac2f0a8f609b1b6044820152606401610cae565b600c54158061220e57506001600160a01b03821630145b8061223d57506024546001600160a01b038381169116148061223d57506023546001600160a01b038381169116145b806122635750600c546001600160a01b0383165f90815260208190526040902054820111155b6122a45760405162461bcd60e51b815260206004820152601260248201527145786365656473206d617842616c616e636560701b6044820152606401610cae565b60085462010000900460ff161580156122c757506008546301000000900460ff16155b80156122db5750600854610100900460ff16155b156124a9576024545f9081906001600160a01b038681169116148061230d57506024546001600160a01b038581169116145b15612334576024546001600160a01b0386811691161461232e576002612331565b60015b90505b60015b60068160ff161015612491575f808360ff16116123845760ff82165f908152600360205260408120600101905b600a91828204019190066003029054906101000a900462ffffff166123cc565b8260ff166001146123aa5760ff82165f9081526003602052604090206001016002612364565b60ff82165f908152600360205260409020600101546301000000900462ffffff165b62ffffff169050805f036123e05750612489565b620186a0858202046123f38830836132d3565b60245460ff84165f908152600360205260409020546001600160a01b039182166101009091049091160361242e576011805482019055612482565b60ff83165f908152600360205260409020600281018054830190555461010090046001600160a01b031661247157601b8054820190556016805482019055612482565b601a80548201905560148054820190555b9390930192505b600101612337565b5081156124a657601380548301905591819003915b50505b6124b48383836132d3565b5f811180156124db57506001600160a01b0382165f9081526002602052604090205460ff16155b15611ae057506001600160a01b03165f818152600260205260408120805460ff191660019081179091556007805491820181559091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b031916909117905550565b6008805469ffffff000000000000001916600160381b62ffffff841690810291909117909155612577575f61258d565b61258d600a548262ffffff16620186a091020490565b600c557f00000000000000000000000000000000000000000000000000000000000000006119095760405162ffffff821681527fd03edfeea801807308f0e9302e347c8a12ad32508cae5bce26e9e2a3654158c99060200161120d565b602780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6008805461ff0019166101001790558015801561265b575060085460ff16155b612bcc575f806011541161266f575f612683565b60026011548161268157612681614250565b045b6025546021549192505f916001600160a01b039081169116146126a6575f6126aa565b601a545b6025546022549192505f916001600160a01b039081169116146126cd575f6126d1565b601b545b90508181018301841580156126e75750600e5481115b1561277c575f84116126f9575f61271f565b600e5461271f9082620186a087028161271457612714614250565b04620186a091020490565b93505f831161272e575f612749565b600e546127499082620186a086028161271457612714614250565b92505f8211612758575f612773565b600e546127739082620186a085028161271457612714614250565b91505081810183015b848061278a5750600d548110155b80156127a65750305f9081526020819052604090205481850111155b15612a005760408051600280825260608201835247925f92919060208301908036833701905050905030815f815181106127e2576127e2614209565b6001600160a01b03928316602091820292909201015260255482519116908290600190811061281357612813614209565b6001600160a01b0392831660209182029290920101526023546128399130911685611f47565b60235460405163791ac94760e01b81526001600160a01b039091169063791ac947906128719086905f90869030904290600401614264565b5f604051808303815f87803b158015612888575f80fd5b505af1925050508015612899575060015b6128ba576023546128b59030906001600160a01b03165f611f47565b6129fd565b601154156128cc576011805487900390555b604080518481524784900360208201819052917f9029ea20319a59447bd88162928acbbbe0955dead46655370929b794e46e8d96910160405180910390a180156129fb576129288185620186a08a028161271457612714614250565b6012805490910190556025546021546001600160a01b039081169116148061296057506025546022546001600160a01b039081169116145b156129fb576025546021546001600160a01b039182169116036129b0576129958185620186a089028161271457612714614250565b601e80549091019055601c805487019055601a805487900390555b6025546022546001600160a01b039182169116036129fb576129e08185620186a088028161271457612714614250565b601f80549091019055601d805486019055601b805486900390555b505b50505b6021546001600160a01b03163014801590612a2c57506025546021546001600160a01b03908116911614155b15612ad057601a54925084158015612a455750600e5483115b15612a5057600e5492505b8480612a5e5750600d548310155b8015612a785750305f908152602081905260409020548311155b15612ad0576021545f90612a95906001600160a01b0316856133ee565b90508015612ace576021546001600160a01b03165f908152600660205260409020805482019055601c805485019055601a805485900390555b505b6022546001600160a01b03163014801590612afc57506025546022546001600160a01b03908116911614155b15612ba057601b54915084158015612b155750600e5482115b15612b2057600e5491505b8480612b2e5750600d548210155b8015612b485750305f908152602081905260409020548211155b15612ba0576022545f90612b65906001600160a01b0316846133ee565b90508015612b9e576022546001600160a01b03165f908152600560205260409020805482019055601d805484019055601b805484900390555b505b50505050612bad81613665565b6009805463ffffffff60581b19164263ffffffff16600160581b021790555b506008805461ff0019169055565b6008805463ff00000019166301000000179055601454158015612c4057506016541580612c405750600854600160981b900462ffffff1615801590612c405750600a54600854612c3b9190600160981b900462ffffff16620186a091020490565b601654105b612f8a575f808060015b60068160ff161015612ed35760ff81165f908152600360205260409020805460028201546101009091046001600160a01b0316901580612c9757506024546001600160a01b038281169116145b15612ca3575050612ecb565b5f8080806001600160a01b038516612e4757602254612cf1906001600160a01b03163014612cd357601d54612cd7565b601b545b6016546002890154620186a0028161271457612714614250565b601954600754919550905f5a90505f5b60175481108015612d155750600185019483115b15612e2357828410612d25575f93505b5f60078580600101965081548110612d3f57612d3f614209565b5f918252602090912001546001600160a01b0316905030811480612d6a57506001600160a01b038116155b80612d8257506024546001600160a01b038281169116145b80612da557506018546001600160a01b0382165f90815260208190526040902054105b15612db05750612d01565b305f90815260208190526040808220546024546001600160a01b03908116845282842054600a5491861685529290932054612e0f938593612e08938f93919092039190910390620186a0028161271457612714614250565b6001613811565b870196505a8303820191505a925050612d01565b60198490558515612e3e5760028a01805487900390559b85019b5b50505050612ec0565b602154612e83906001600160a01b03163014612e6557601c54612e69565b601a545b6014546002890154620186a0028161271457612714614250565b9350835f03612e9757505050505050612ecb565b612ea285855f613811565b92508215612ec0576002860180548490039055600190990198968201965b989098019750505050505b600101612c4a565b506009805466ffffffff0000001916630100000063ffffffff4216021790558015612f35576014805482900390556040518181527fbb245b3c380b63918dc25ab2cc2e4b6939c4d58ffd95ea052b685a031e1ad2979060200160405180910390a15b8115612f8657601680548390039055601580548301905560408051838152602081018590527fac4c4b96e3856cb20170077826b7701a887bdaf8d743f369b438133249a1f82f910160405180910390a15b5050505b6008805463ff00000019169055565b60058360ff161115612fa9575f80fd5b6001600160a01b0382163014801590612fcd57506001600160a01b03821661dead14155b612fd5575f80fd5b60ff83165f9081526003602090815260409182902060018101805485516008805462ffffff60501b19811662ffffff948516909303600160501b808304861691909101851681029384178084558654988b015162ffffff60681b1990951665ffffffffffff60501b199093169290921763010000009098048516909303600160681b9182900485160184160295909517808655925495870151600160801b80850484166601000000000000909804841690910396909601821690950262ffffff60801b19909216919091179283905590926161a89204161180159061311657506008546161a8600160681b90910462ffffff16118015906130e757506008546161a8600160801b90910462ffffff1611155b801561311657506008546161a8600160681b820462ffffff908116600160801b90930481169290920190911611155b61314d5760405162461bcd60e51b8152602060048201526008602482015267090d2ced040a8c2f60c31b6044820152606401610cae565b8054610100600160a81b0319166101006001600160a01b0385160217815561317a60018201836003613d11565b50805460ff1661319057805460ff191660011781555b7f93dd041a76c0a756b346cffaf7b1e0b1c3f26f0c908f8a4600c5e9d530fa21a18484846040516131c3939291906142d5565b60405180910390a150505050565b6008805462ffffff60e01b1916600160e01b62ffffff858116918202929092179092556009805462ffffff1916918416919091179055600a5461321891620186a091020490565b600f55600a54620186a062ffffff92909216020460105550565b6008805466ffffff00000000191664010000000062ffffff841690810291909117909155613260575f613276565b613276600a548262ffffff16620186a091020490565b600b557f00000000000000000000000000000000000000000000000000000000000000006119095760405162ffffff821681527ff01936354f43c5b49521c6c3fdc9740709976ee07acac3ebf79fbd6282cda1959060200161120d565b6001600160a01b038316158015906132f357506001600160a01b03821615155b61333f5760405162461bcd60e51b815260206004820152601d60248201527f5472616e736665722066726f6d2f746f207a65726f20616464726573730000006044820152606401610cae565b6001600160a01b0383165f908152602081905260409020548111156133765760405162461bcd60e51b8152600401610cae906141c5565b80156133a9576001600160a01b038084165f90815260208190526040808220805485900390559184168152208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611f9b91815260200190565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038516906370a0823190602401602060405180830381865afa158015613434573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061345891906141ae565b604080516003808252608082019092529192505f91906020820160608036833701905050905030815f8151811061349157613491614209565b6001600160a01b0392831660209182029290920101526025548251911690829060019081106134c2576134c2614209565b60200260200101906001600160a01b031690816001600160a01b03168152505084816002815181106134f6576134f6614209565b6001600160a01b03928316602091820292909201015260235461351c9130911686611f47565b602354604051635c11d79560e01b81526001600160a01b0390911690635c11d795906135549087905f90869030904290600401614264565b5f604051808303815f87803b15801561356b575f80fd5b505af192505050801561357c575060015b61359d576023546135989030906001600160a01b03165f611f47565b61365d565b6040516370a0823160e01b815230600482015282906001600160a01b038716906370a0823190602401602060405180830381865afa1580156135e1573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061360591906141ae565b61360f9190614303565b604080516001600160a01b0388168152602081018790529081018290529093507fa82a03c1e8613c6192a82386fbb3690070528b0dd8bcae8a5c82d9ef937d7f769060600160405180910390a15b505092915050565b801580156136805750600f5460115410806136805750601254155b156136885750565b5f8115801561369a5750601054601154115b6136a6576011546136aa565b6010545b90505f821580156136be5750601054601154115b6136ca576012546136f3565b6136f3601254601154601054816136e3576136e3614250565b04620186a002620186a091020490565b60235490915061370e9030906001600160a01b031684611f47565b60235460265460405163f305d71960e01b8152306004820152602481018590525f6044820181905260648201526001600160a01b0391821660848201524260a482015291169063f305d71990839060c40160606040518083038185885af19350505050801561379a575060408051601f3d908101601f1916820190925261379791810190614316565b60015b6137b657602354611ae09030906001600160a01b03165f611f47565b60408051848152602081018490529081018290527f947eb7d5785b0534dc368370fd3574434082455556a747116a88abea1ec6ceba9060600160405180910390a1505060118054849003905550601280548290039055505050565b5f825f0361382057505f610e77565b3082613837576021546001600160a01b0316613844565b6022546001600160a01b03165b6001600160a01b0316036139cc575f600c5411801561387d5750600c546001600160a01b0385165f908152602081905260409020548401115b156138d5576001600160a01b0384165f90815260208190526040902054600c54116138a8575f6138c5565b6001600160a01b0384165f90815260208190526040902054600c54035b9250825f036138d557505f610e77565b6138e03085856132d3565b811561393957601b805484900390556001600160a01b038085165f908152600260209081526040808320602280548616855260019190910183528184208054890190555490931682526004905220805484019055613943565b601a805484900390555b6001600160a01b0384165f9081526002602052604090205460ff166139c7576001600160a01b0384165f818152600260205260408120805460ff191660019081179091556007805491820181559091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b03191690911790555b613cdb565b5f826139da57601c546139de565b601d545b620186a08502816139f1576139f1614250565b60255491900491505f906001600160a01b031684613a1a576021546001600160a01b0316613a27565b6022546001600160a01b03165b6001600160a01b031603613ae157613a5484613a4557601e54613a49565b601f545b83620186a091020490565b90505f866001600160a01b031682617530906040515f60405180830381858888f193505050503d805f8114613aa4576040519150601f19603f3d011682016040523d82523d5f602084013e613aa9565b606091505b5050905080613abd575f9350505050610e77565b8415613ad157601f80548390039055613adb565b601e805483900390555b50613c75565b613b2d84613b08576021546001600160a01b03165f90815260066020526040902054613a49565b6022546001600160a01b03165f9081526005602052604090205483620186a091020490565b90508315613bd75760225460405163a9059cbb60e01b81526001600160a01b038881166004830152602482018490529091169063a9059cbb906044016020604051808303815f875af1925050508015613ba3575060408051601f3d908101601f19168201909252613ba0918101906141ee565b60015b613bb1575f92505050610e77565b506022546001600160a01b03165f90815260056020526040902080548290039055613c75565b60215460405163a9059cbb60e01b81526001600160a01b038881166004830152602482018490529091169063a9059cbb906044016020604051808303815f875af1925050508015613c45575060408051601f3d908101601f19168201909252613c42918101906141ee565b60015b613c53575f92505050610e77565b506021546001600160a01b03165f908152600660205260409020805482900390555b8315613cce57601d805486900390556001600160a01b038087165f908152600260209081526040808320602280548616855260019190910183528184208054870190555490931682526004905220805482019055613cd8565b601c805486900390555b50505b509092915050565b60405180606001604052805f6001600160a01b03168152602001613d05613da5565b81526020015f81525090565b600183019183908215613d99579160200282015f5b83821115613d6857835183826101000a81548162ffffff021916908362ffffff1602179055509260200192600301602081600201049283019260010302613d26565b8015613d975782816101000a81549062ffffff0219169055600301602081600201049283019260010302613d68565b505b50611565929150613dc3565b60405180606001604052806003906020820280368337509192915050565b5b80821115611565575f8155600101613dc4565b5f81518084525f5b81811015613dfb57602081850181015186830182015201613ddf565b505f602082860101526020601f19601f83011685010191505092915050565b602081525f610e776020830184613dd7565b6001600160a01b0381168114611909575f80fd5b5f8060408385031215613e51575f80fd5b8235613e5c81613e2c565b946020939093013593505050565b5f805f60608486031215613e7c575f80fd5b8335613e8781613e2c565b92506020840135613e9781613e2c565b929592945050506040919091013590565b5f60208284031215613eb8575f80fd5b8135610e7781613e2c565b8015158114611909575f80fd5b5f60208284031215613ee0575f80fd5b8135610e7781613ec3565b60c081525f613efd60c0830189613dd7565b8281036020840152613f0f8189613dd7565b60ff881660408501526001600160a01b03871660608501526080840186905283810360a08501529050613f428185613dd7565b9998505050505050505050565b5f60208284031215613f5f575f80fd5b5035919050565b803562ffffff81168114613f78575f80fd5b919050565b5f60208284031215613f8d575f80fd5b610e7782613f66565b5f8060408385031215613fa7575f80fd5b613fb083613f66565b9150613fbe60208401613f66565b90509250929050565b805f5b6003811015610e5657815162ffffff16845260209384019390910190600101613fca565b602080825282518282018190525f919060409081850190868401855b8281101561404c57815180516001600160a01b031685528681015161403188870182613fc7565b50850151608085015260a0909301929085019060010161400a565b5091979650505050505050565b634e487b7160e01b5f52604160045260245ffd5b5f805f60a0848603121561407f575f80fd5b833560ff8116811461408f575f80fd5b92506020848101356140a081613e2c565b9250605f850186136140b0575f80fd5b6040516060810181811067ffffffffffffffff821117156140d3576140d3614059565b6040528060a08701888111156140e7575f80fd5b604088015b8181101561410a576140fd81613f66565b83529184019184016140ec565b50505080925050509250925092565b5f806040838503121561412a575f80fd5b823561413581613e2c565b9150602083013561414581613e2c565b809150509250929050565b600181811c9082168061416457607f821691505b60208210810361418257634e487b7160e01b5f52602260045260245ffd5b50919050565b6020808252600c908201526b155b985d5d1a1bdc9a5e995960a21b604082015260600190565b5f602082840312156141be575f80fd5b5051919050565b6020808252600f908201526e457863656564732062616c616e636560881b604082015260600190565b5f602082840312156141fe575f80fd5b8151610e7781613ec3565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b62ffffff81811683821602808216919082811461365d5761365d61421d565b634e487b7160e01b5f52601260045260245ffd5b5f60a08201878352602087602085015260a0604085015281875180845260c0860191506020890193505f5b818110156142b45784516001600160a01b03168352938301939183019160010161428f565b50506001600160a01b03969096166060850152505050608001529392505050565b60ff841681526001600160a01b038316602082015260a081016142fb6040830184613fc7565b949350505050565b81810381811115610c7e57610c7e61421d565b5f805f60608486031215614328575f80fd5b835192506020840151915060408401519050925092509256fea2646970667358221220f610fa8ffe573fd7a1349d9e3a60cdd8e15e2a959b96eb6388f4c9d6b4a54cc564736f6c63430008180033a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688

Deployed Bytecode

0x6080604052600436106103a1575f3560e01c80638324c3b9116101e4578063c29215831161010b578063d8454a82116100a4578063f2cda82e11610076578063f2cda82e14610b43578063f2fde38b14610b62578063f7c3b38f14610b81578063f7de0e5714610ba2578063f868302414610bbf57005b8063d8454a8214610add578063da88d01a14610af1578063dd62ed3e14610b10578063e92871f614610b2f57005b8063ceedfa50116100dd578063ceedfa5014610a27578063d232c22014610a47578063d551160914610a9f578063d6a018eb14610abe57005b8063c2921583146109ce578063c77e006d146109eb578063c78fe0d4146109ff578063cc1776d314610a1357005b806396ce07951161017d578063a4d8971a1161014f578063a4d8971a14610954578063a5596b4f14610973578063a9059cbb14610992578063b81a0145146109b157005b806396ce0795146108e657806397a26b9e146108fa5780639c5ef8d714610921578063a457c2d71461093557005b80638d8350ca116101b65780638d8350ca146108775780638da5cb5b1461089657806395101f90146108b357806395d89b41146108d257005b80638324c3b91461082757806385a6b3ae1461083b5780638a8c523c1461084f5780638bf1acff1461086357005b806337061ab2116102c85780635f6417581161026157806370b749d51161023357806370b749d5146107cb578063715018a6146107df57806375de1496146107f3578063770048511461081357005b80635f641758146107385780636b979993146107575780636f05be971461077657806370a082311461079757005b80634b7d9db41161029a5780634b7d9db4146106af5780634f7041a5146106c657806354fd4d50146106ee5780635a0d4f881461071b57005b806337061ab21461063357806339509351146106525780633ed8a1691461067157806344b691ff1461069057005b806318160ddd1161033a5780632cdf2c351161030c5780632cdf2c351461056f578063313ce5671461058e57806332acf3de146105cb578063370158ea1461060d57005b806318160ddd146104ec578063211600e31461050057806323b872dd146105315780632623e9751461055057005b8063095ea7b311610373578063095ea7b31461043a5780630fcb2fe7146104595780631171bda914610484578063150bf8ab146104a357005b8063064a59d0146103aa57806306fdde03146103de578063070d8ba7146103ff57806307e9652c1461041d57005b366103a857005b005b3480156103b5575f80fd5b50600954600160381b900463ffffffff1615155b60405190151581526020015b60405180910390f35b3480156103e9575f80fd5b506103f2610bde565b6040516103d59190613e1a565b34801561040a575f80fd5b506017545b6040519081526020016103d5565b348015610428575f80fd5b5060085462010000900460ff166103c9565b348015610445575f80fd5b506103c9610454366004613e40565b610c6e565b348015610464575f80fd5b506022546001600160a01b03165f9081526004602052604090205461040f565b34801561048f575f80fd5b506103a861049e366004613e6a565b610c84565b3480156104ae575f80fd5b5061040f6104bd366004613ea8565b6001600160a01b039081165f908152600260209081526040808320602254909416835260019093019052205490565b3480156104f7575f80fd5b50600a5461040f565b34801561050b575f80fd5b506022546001600160a01b03165b6040516001600160a01b0390911681526020016103d5565b34801561053c575f80fd5b506103c961054b366004613e6a565b610e5c565b34801561055b575f80fd5b506103a861056a366004613ed0565b610e7e565b34801561057a575f80fd5b506103a8610589366004613e6a565b610f1d565b348015610599575f80fd5b5060405160ff7f00000000000000000000000000000000000000000000000000000000000000121681526020016103d5565b3480156105d6575f80fd5b5060085462ffffff600160b01b8204811691600160c81b9004165b6040805162ffffff9384168152929091166020830152016103d5565b348015610618575f80fd5b50610621610f82565b6040516103d596959493929190613eeb565b34801561063e575f80fd5b506103a861064d366004613f4f565b61110d565b34801561065d575f80fd5b506103c961066c366004613e40565b61114b565b34801561067c575f80fd5b506103a861068b366004613f7d565b611162565b34801561069b575f80fd5b506103a86106aa366004613f96565b611218565b3480156106ba575f80fd5b5060085460ff166103c9565b3480156106d1575f80fd5b506106da611364565b60405162ffffff90911681526020016103d5565b3480156106f9575f80fd5b50604080518082019091526005815264189718171960d91b60208201526103f2565b348015610726575f80fd5b506021546001600160a01b0316610519565b348015610743575f80fd5b506106da610752366004613ea8565b611373565b348015610762575f80fd5b506103a8610771366004613f4f565b611400565b348015610781575f80fd5b5061078a611444565b6040516103d59190613fee565b3480156107a2575f80fd5b5061040f6107b1366004613ea8565b6001600160a01b03165f9081526020819052604090205490565b3480156107d6575f80fd5b5060185461040f565b3480156107ea575f80fd5b506103a8611569565b3480156107fe575f80fd5b50600854600160381b900462ffffff166106da565b34801561081e575f80fd5b506103a86115b1565b348015610832575f80fd5b506103a86115f2565b348015610846575f80fd5b5060155461040f565b34801561085a575f80fd5b506103a8611657565b34801561086e575f80fd5b506106da611732565b348015610882575f80fd5b506106da610891366004613ea8565b611738565b3480156108a1575f80fd5b506027546001600160a01b0316610519565b3480156108be575f80fd5b506106da6108cd366004613ea8565b611775565b3480156108dd575f80fd5b506103f26117cb565b3480156108f1575f80fd5b506103e86106da565b348015610905575f80fd5b5060085460095462ffffff600160e01b909204821691166105f1565b34801561092c575f80fd5b506103a86117da565b348015610940575f80fd5b506103c961094f366004613e40565b611836565b34801561095f575f80fd5b506103a861096e366004613ed0565b611896565b34801561097e575f80fd5b506103a861098d366004613ed0565b61190c565b34801561099d575f80fd5b506103c96109ac366004613e40565b611967565b3480156109bc575f80fd5b506026546001600160a01b0316610519565b3480156109d9575f80fd5b506024546001600160a01b0316610519565b3480156109f6575f80fd5b506103a8611973565b348015610a0a575f80fd5b506103a86119d6565b348015610a1e575f80fd5b506106da611a3d565b348015610a32575f80fd5b50600854600160981b900462ffffff166106da565b348015610a52575f80fd5b5060205460ff8082169161010081048216916301000000820481169162010000900416604080519415158552921515602085015290151591830191909152151560608201526080016103d5565b348015610aaa575f80fd5b506103a8610ab936600461406d565b611a47565b348015610ac9575f80fd5b506103a8610ad8366004613f96565b611ae5565b348015610ae8575f80fd5b5060135461040f565b348015610afc575f80fd5b506103a8610b0b366004613f7d565b611c03565b348015610b1b575f80fd5b5061040f610b2a366004614119565b611cad565b348015610b3a575f80fd5b506103a8611cd7565b348015610b4e575f80fd5b506103a8610b5d366004613e40565b611d38565b348015610b6d575f80fd5b506103a8610b7c366004613ea8565b611e3b565b348015610b8c575f80fd5b50600854640100000000900462ffffff166106da565b348015610bad575f80fd5b506023546001600160a01b0316610519565b348015610bca575f80fd5b506103a8610bd9366004613f7d565b611e80565b606060288054610bed90614150565b80601f0160208091040260200160405190810160405280929190818152602001828054610c1990614150565b8015610c645780601f10610c3b57610100808354040283529160200191610c64565b820191905f5260205f20905b815481529060010190602001808311610c4757829003601f168201915b5050505050905090565b5f610c7a338484611f47565b5060015b92915050565b6027546001600160a01b03163314610cb75760405162461bcd60e51b8152600401610cae90614188565b60405180910390fd5b6040516370a0823160e01b81523060048201525f906001600160a01b038516906370a0823190602401602060405180830381865afa158015610cfb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d1f91906141ae565b90505f6001600160a01b0385163014610da4576022546001600160a01b03868116911614610d4d575f610d68565b6022546001600160a01b03165f908152600560205260409020545b6021546001600160a01b03878116911614610d83575f610d9e565b6021546001600160a01b03165f908152600660205260409020545b01610db0565b601154601b54601a5401015b90508282821015610dc15781610dc3565b825b83031015610de35760405162461bcd60e51b8152600401610cae906141c5565b505060405163a9059cbb60e01b81526001600160a01b0383811660048301526024820183905284169063a9059cbb906044015b6020604051808303815f875af1158015610e32573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e5691906141ee565b50505050565b5f610e68843384611fa8565b610e7384848461200b565b5060015b9392505050565b6027546001600160a01b03163314610ea85760405162461bcd60e51b8152600401610cae90614188565b6020546301000000900460ff1615610ebe575f80fd5b801580610ed557506023546001600160a01b031615155b610f0a5760405162461bcd60e51b815260206004820152600660248201526509cde40888ab60d31b6044820152606401610cae565b6008805460ff1916911515919091179055565b6027546001600160a01b03163314610f475760405162461bcd60e51b8152600401610cae90614188565b604051632142170760e11b81523060048201526001600160a01b038381166024830152604482018390528416906342842e0e90606401610e16565b6060805f805f6060602860297f000000000000000000000000000000000000000000000000000000000000001260275f9054906101000a90046001600160a01b0316600a5460405180604001604052806005815260200164189718171960d91b815250858054610ff190614150565b80601f016020809104026020016040519081016040528092919081815260200182805461101d90614150565b80156110685780601f1061103f57610100808354040283529160200191611068565b820191905f5260205f20905b81548152906001019060200180831161104b57829003601f168201915b5050505050955084805461107b90614150565b80601f01602080910402602001604051908101604052809291908181526020018280546110a790614150565b80156110f25780601f106110c9576101008083540402835291602001916110f2565b820191905f5260205f20905b8154815290600101906020018083116110d557829003601f168201915b50505050509450955095509550955095509550909192939495565b6027546001600160a01b031633146111375760405162461bcd60e51b8152600401610cae90614188565b62030d40811015611146575f80fd5b601755565b5f610c7a33848461115c3388611cad565b01611f47565b6027546001600160a01b0316331461118c5760405162461bcd60e51b8152600401610cae90614188565b602054610100900460ff16156111a0575f80fd5b62ffffff811615806111cb575060648162ffffff16101580156111cb5750620186a062ffffff821611155b6111d3575f80fd5b6111dc81612547565b60405162ffffff821681527fd03edfeea801807308f0e9302e347c8a12ad32508cae5bce26e9e2a3654158c9906020015b60405180910390a150565b6027546001600160a01b031633146112425760405162461bcd60e51b8152600401610cae90614188565b6020546301000000900460ff1615611258575f80fd5b60018262ffffff161015801561127557506103e88262ffffff1611155b6112b05760405162461bcd60e51b815260206004820152600c60248201526b302e3030312520746f20312560a01b6044820152606401610cae565b8162ffffff168162ffffff16101580156112d157506103e88162ffffff1611155b61130c5760405162461bcd60e51b815260206004820152600c60248201526b302e3030312520746f20312560a01b6044820152606401610cae565b6008805465ffffffffffff60b01b1916600160b01b62ffffff80861691820262ffffff60c81b191692909217600160c81b92851692830217909255600a54620186a0928102839004600d550204600e555050565b5050565b5f61136e33611775565b905090565b6008545f9062010000900460ff161561138d57505f919050565b6001600160a01b0382163014806113b157506027546001600160a01b038381169116145b806113c957506024546001600160a01b038381169116145b806113e157506023546001600160a01b038381169116145b6113f957600854600160801b900462ffffff16610c7e565b5f92915050565b6027546001600160a01b0316331461142a5760405162461bcd60e51b8152600401610cae90614188565b60205462010000900460ff161561143f575f80fd5b601855565b60408051600580825260c08201909252606091816020015b611464613ce3565b81526020019060019003908161145c57905050905060015b60068160ff16101561156557604080516060808201835260ff84165f81815260036020818152868320805461010090046001600160a01b0316875293835281815286519485019687905294959486019460019093019290918390855b82829054906101000a900462ffffff1662ffffff16815260200190600301906020826002010492830192600103820291508084116114d85790505050505050815260200160035f8460ff1660ff1681526020019081526020015f2060020154815250826001830360ff168151811061155257611552614209565b602090810291909101015260010161147c565b5090565b6027546001600160a01b031633146115935760405162461bcd60e51b8152600401610cae90614188565b6020805463ffffffff191663010101011790556115af5f6125ea565b565b60085460ff1680156115cb5750600854610100900460ff16155b80156115e157506008546301000000900460ff16155b6115e9575f80fd5b6115af5f61263b565b6027546001600160a01b0316331461161c5760405162461bcd60e51b8152600401610cae90614188565b6020805462ff00001916620100001790556040517fb18b29d65a3b95dc80df0b9528f12b8592bd02395ca19228958e8b7cdf3ddd2b905f90a1565b6027546001600160a01b031633146116815760405162461bcd60e51b8152600401610cae90614188565b6020546301000000900460ff1615611697575f80fd5b600954600160381b900463ffffffff16156116e65760405162461bcd60e51b815260206004820152600f60248201526e105b1c9958591e48195b98589b1959608a1b6044820152606401610cae565b600980546affffffff000000000000001916600160381b63ffffffff4216021790556040517f799663458a5ef2936f7fa0c99b3336c69c25890f82974f04e811e5bb359186c7905f90a1565b5f61136e335b5f6001600160a01b03821630148061175d57506024546001600160a01b038381169116145b6113f957600854600160501b900462ffffff16610c7e565b6008545f9062010000900460ff161561178f57505f919050565b6001600160a01b0382163014806117b357506024546001600160a01b038381169116145b6113f957600854600160681b900462ffffff16610c7e565b606060298054610bed90614150565b6027546001600160a01b031633146118045760405162461bcd60e51b8152600401610cae90614188565b600854610100900460ff1615801561182657506008546301000000900460ff16155b61182e575f80fd5b6115af612bda565b5f806118423385611cad565b9050828110156118895760405162461bcd60e51b81526020600482015260126024820152714e6567617469766520616c6c6f77616e636560701b6044820152606401610cae565b610e733385858403611f47565b6027546001600160a01b031633146118c05760405162461bcd60e51b8152600401610cae90614188565b80806118ce575060085460ff165b80156118e25750600854610100900460ff16155b80156118f857506008546301000000900460ff16155b611900575f80fd5b6119098161263b565b50565b6027546001600160a01b031633146119365760405162461bcd60e51b8152600401610cae90614188565b60205462010000900460ff161561194b575f80fd5b60088054911515620100000262ff000019909216919091179055565b5f610c7a33848461200b565b6027546001600160a01b0316331461199d5760405162461bcd60e51b8152600401610cae90614188565b6020805461ff0019166101001790556040517f6754c879eecdc6d0fbd95c51f8e377373a9f6be654462f792774fe3740e317ee905f90a1565b6027546001600160a01b03163314611a005760405162461bcd60e51b8152600401610cae90614188565b6020805463ff000000191663010000001790556040517ff7f7205ed48f7a35df9b5857667bdee0189d5d7cd80588f217a82641c3b4d08c905f90a1565b5f61136e33611373565b6027546001600160a01b03163314611a715760405162461bcd60e51b8152600401610cae90614188565b60205462010000900460ff1615611a86575f80fd5b60018360ff1610158015611a9e575060058360ff1611155b611ad55760405162461bcd60e51b815260206004820152600860248201526714995cd95c9d995960c21b6044820152606401610cae565b611ae0838383612f99565b505050565b6027546001600160a01b03163314611b0f5760405162461bcd60e51b8152600401610cae90614188565b6020546301000000900460ff1615611b25575f80fd5b600a8262ffffff1610158015611b515750611b436103e86064614231565b62ffffff168262ffffff1611155b611b8d5760405162461bcd60e51b815260206004820152600d60248201526c302e30312520746f203130302560981b6044820152606401610cae565b8162ffffff168162ffffff1610158015611bbd5750611baf6103e86064614231565b62ffffff168162ffffff1611155b611bf95760405162461bcd60e51b815260206004820152600d60248201526c302e30312520746f203130302560981b6044820152606401610cae565b61136082826131d1565b6027546001600160a01b03163314611c2d5760405162461bcd60e51b8152600401610cae90614188565b60205460ff1615611c3c575f80fd5b62ffffff81161580611c67575060648162ffffff1610158015611c675750620186a062ffffff821611155b611c6f575f80fd5b611c7881613232565b60405162ffffff821681527ff01936354f43c5b49521c6c3fdc9740709976ee07acac3ebf79fbd6282cda1959060200161120d565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6027546001600160a01b03163314611d015760405162461bcd60e51b8152600401610cae90614188565b6020805460ff191660011790556040517fcc2f10fb1214ece03bcb178c4d75943daee74aff93182bfb58ba9b8ef5d8c5aa905f90a1565b6027546001600160a01b03163314611d625760405162461bcd60e51b8152600401610cae90614188565b60255460225447915f916001600160a01b03908116911614611d84575f611d88565b601f545b6025546021546001600160a01b03908116911614611da6575f611daa565b601e545b0190508282821015611dbc5781611dbe565b825b83031015611dde5760405162461bcd60e51b8152600401610cae906141c5565b50505f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114611e29576040519150601f19603f3d011682016040523d82523d5f602084013e611e2e565b606091505b5050905080611ae0575f80fd5b6027546001600160a01b03163314611e655760405162461bcd60e51b8152600401610cae90614188565b6001600160a01b038116611e77575f80fd5b611909816125ea565b6027546001600160a01b03163314611eaa5760405162461bcd60e51b8152600401610cae90614188565b60205462010000900460ff1615611ebf575f80fd5b62ffffff81161580611ee95750600a8162ffffff1610158015611ee957506103e862ffffff821611155b611f235760405162461bcd60e51b815260206004820152600b60248201526a302e30312520746f20312560a81b6044820152606401610cae565b6008805462ffffff909216600160981b0262ffffff60981b19909216919091179055565b6001600160a01b038381165f8181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b5f611fb38484611cad565b905081811015611ffe5760405162461bcd60e51b8152602060048201526016602482015275496e73756666696369656e7420616c6c6f77616e636560501b6044820152606401610cae565b610e568484848403611f47565b6008546301000000900460ff1615801561202d5750600854610100900460ff16155b801561206057506024546001600160a01b0384811691161480159061206057506023546001600160a01b03848116911614155b156120765761206e5f61263b565b612076612bda565b5f8111801561209357506027546001600160a01b03848116911614155b80156120ad57506027546001600160a01b03838116911614155b80156120c257506001600160a01b0383163014155b80156120d757506001600160a01b0382163014155b80156120f157506023546001600160a01b03838116911614155b156124a9576024546001600160a01b0384811691161480159061212257506024546001600160a01b03838116911614155b8061216b57506024546001600160a01b038481169116148061215157506024546001600160a01b038381169116145b801561216b5750600954600160381b900463ffffffff1615155b6121aa5760405162461bcd60e51b815260206004820152601060248201526f151c98591a5b99c8191a5cd8589b195960821b6044820152606401610cae565b600b5415806121bb5750600b548111155b6121f75760405162461bcd60e51b815260206004820152600d60248201526c08af0c6cacac8e640dac2f0a8f609b1b6044820152606401610cae565b600c54158061220e57506001600160a01b03821630145b8061223d57506024546001600160a01b038381169116148061223d57506023546001600160a01b038381169116145b806122635750600c546001600160a01b0383165f90815260208190526040902054820111155b6122a45760405162461bcd60e51b815260206004820152601260248201527145786365656473206d617842616c616e636560701b6044820152606401610cae565b60085462010000900460ff161580156122c757506008546301000000900460ff16155b80156122db5750600854610100900460ff16155b156124a9576024545f9081906001600160a01b038681169116148061230d57506024546001600160a01b038581169116145b15612334576024546001600160a01b0386811691161461232e576002612331565b60015b90505b60015b60068160ff161015612491575f808360ff16116123845760ff82165f908152600360205260408120600101905b600a91828204019190066003029054906101000a900462ffffff166123cc565b8260ff166001146123aa5760ff82165f9081526003602052604090206001016002612364565b60ff82165f908152600360205260409020600101546301000000900462ffffff165b62ffffff169050805f036123e05750612489565b620186a0858202046123f38830836132d3565b60245460ff84165f908152600360205260409020546001600160a01b039182166101009091049091160361242e576011805482019055612482565b60ff83165f908152600360205260409020600281018054830190555461010090046001600160a01b031661247157601b8054820190556016805482019055612482565b601a80548201905560148054820190555b9390930192505b600101612337565b5081156124a657601380548301905591819003915b50505b6124b48383836132d3565b5f811180156124db57506001600160a01b0382165f9081526002602052604090205460ff16155b15611ae057506001600160a01b03165f818152600260205260408120805460ff191660019081179091556007805491820181559091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b031916909117905550565b6008805469ffffff000000000000001916600160381b62ffffff841690810291909117909155612577575f61258d565b61258d600a548262ffffff16620186a091020490565b600c557f00000000000000000000000000000000000000000000000000000000000000016119095760405162ffffff821681527fd03edfeea801807308f0e9302e347c8a12ad32508cae5bce26e9e2a3654158c99060200161120d565b602780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6008805461ff0019166101001790558015801561265b575060085460ff16155b612bcc575f806011541161266f575f612683565b60026011548161268157612681614250565b045b6025546021549192505f916001600160a01b039081169116146126a6575f6126aa565b601a545b6025546022549192505f916001600160a01b039081169116146126cd575f6126d1565b601b545b90508181018301841580156126e75750600e5481115b1561277c575f84116126f9575f61271f565b600e5461271f9082620186a087028161271457612714614250565b04620186a091020490565b93505f831161272e575f612749565b600e546127499082620186a086028161271457612714614250565b92505f8211612758575f612773565b600e546127739082620186a085028161271457612714614250565b91505081810183015b848061278a5750600d548110155b80156127a65750305f9081526020819052604090205481850111155b15612a005760408051600280825260608201835247925f92919060208301908036833701905050905030815f815181106127e2576127e2614209565b6001600160a01b03928316602091820292909201015260255482519116908290600190811061281357612813614209565b6001600160a01b0392831660209182029290920101526023546128399130911685611f47565b60235460405163791ac94760e01b81526001600160a01b039091169063791ac947906128719086905f90869030904290600401614264565b5f604051808303815f87803b158015612888575f80fd5b505af1925050508015612899575060015b6128ba576023546128b59030906001600160a01b03165f611f47565b6129fd565b601154156128cc576011805487900390555b604080518481524784900360208201819052917f9029ea20319a59447bd88162928acbbbe0955dead46655370929b794e46e8d96910160405180910390a180156129fb576129288185620186a08a028161271457612714614250565b6012805490910190556025546021546001600160a01b039081169116148061296057506025546022546001600160a01b039081169116145b156129fb576025546021546001600160a01b039182169116036129b0576129958185620186a089028161271457612714614250565b601e80549091019055601c805487019055601a805487900390555b6025546022546001600160a01b039182169116036129fb576129e08185620186a088028161271457612714614250565b601f80549091019055601d805486019055601b805486900390555b505b50505b6021546001600160a01b03163014801590612a2c57506025546021546001600160a01b03908116911614155b15612ad057601a54925084158015612a455750600e5483115b15612a5057600e5492505b8480612a5e5750600d548310155b8015612a785750305f908152602081905260409020548311155b15612ad0576021545f90612a95906001600160a01b0316856133ee565b90508015612ace576021546001600160a01b03165f908152600660205260409020805482019055601c805485019055601a805485900390555b505b6022546001600160a01b03163014801590612afc57506025546022546001600160a01b03908116911614155b15612ba057601b54915084158015612b155750600e5482115b15612b2057600e5491505b8480612b2e5750600d548210155b8015612b485750305f908152602081905260409020548211155b15612ba0576022545f90612b65906001600160a01b0316846133ee565b90508015612b9e576022546001600160a01b03165f908152600560205260409020805482019055601d805484019055601b805484900390555b505b50505050612bad81613665565b6009805463ffffffff60581b19164263ffffffff16600160581b021790555b506008805461ff0019169055565b6008805463ff00000019166301000000179055601454158015612c4057506016541580612c405750600854600160981b900462ffffff1615801590612c405750600a54600854612c3b9190600160981b900462ffffff16620186a091020490565b601654105b612f8a575f808060015b60068160ff161015612ed35760ff81165f908152600360205260409020805460028201546101009091046001600160a01b0316901580612c9757506024546001600160a01b038281169116145b15612ca3575050612ecb565b5f8080806001600160a01b038516612e4757602254612cf1906001600160a01b03163014612cd357601d54612cd7565b601b545b6016546002890154620186a0028161271457612714614250565b601954600754919550905f5a90505f5b60175481108015612d155750600185019483115b15612e2357828410612d25575f93505b5f60078580600101965081548110612d3f57612d3f614209565b5f918252602090912001546001600160a01b0316905030811480612d6a57506001600160a01b038116155b80612d8257506024546001600160a01b038281169116145b80612da557506018546001600160a01b0382165f90815260208190526040902054105b15612db05750612d01565b305f90815260208190526040808220546024546001600160a01b03908116845282842054600a5491861685529290932054612e0f938593612e08938f93919092039190910390620186a0028161271457612714614250565b6001613811565b870196505a8303820191505a925050612d01565b60198490558515612e3e5760028a01805487900390559b85019b5b50505050612ec0565b602154612e83906001600160a01b03163014612e6557601c54612e69565b601a545b6014546002890154620186a0028161271457612714614250565b9350835f03612e9757505050505050612ecb565b612ea285855f613811565b92508215612ec0576002860180548490039055600190990198968201965b989098019750505050505b600101612c4a565b506009805466ffffffff0000001916630100000063ffffffff4216021790558015612f35576014805482900390556040518181527fbb245b3c380b63918dc25ab2cc2e4b6939c4d58ffd95ea052b685a031e1ad2979060200160405180910390a15b8115612f8657601680548390039055601580548301905560408051838152602081018590527fac4c4b96e3856cb20170077826b7701a887bdaf8d743f369b438133249a1f82f910160405180910390a15b5050505b6008805463ff00000019169055565b60058360ff161115612fa9575f80fd5b6001600160a01b0382163014801590612fcd57506001600160a01b03821661dead14155b612fd5575f80fd5b60ff83165f9081526003602090815260409182902060018101805485516008805462ffffff60501b19811662ffffff948516909303600160501b808304861691909101851681029384178084558654988b015162ffffff60681b1990951665ffffffffffff60501b199093169290921763010000009098048516909303600160681b9182900485160184160295909517808655925495870151600160801b80850484166601000000000000909804841690910396909601821690950262ffffff60801b19909216919091179283905590926161a89204161180159061311657506008546161a8600160681b90910462ffffff16118015906130e757506008546161a8600160801b90910462ffffff1611155b801561311657506008546161a8600160681b820462ffffff908116600160801b90930481169290920190911611155b61314d5760405162461bcd60e51b8152602060048201526008602482015267090d2ced040a8c2f60c31b6044820152606401610cae565b8054610100600160a81b0319166101006001600160a01b0385160217815561317a60018201836003613d11565b50805460ff1661319057805460ff191660011781555b7f93dd041a76c0a756b346cffaf7b1e0b1c3f26f0c908f8a4600c5e9d530fa21a18484846040516131c3939291906142d5565b60405180910390a150505050565b6008805462ffffff60e01b1916600160e01b62ffffff858116918202929092179092556009805462ffffff1916918416919091179055600a5461321891620186a091020490565b600f55600a54620186a062ffffff92909216020460105550565b6008805466ffffff00000000191664010000000062ffffff841690810291909117909155613260575f613276565b613276600a548262ffffff16620186a091020490565b600b557f00000000000000000000000000000000000000000000000000000000000000016119095760405162ffffff821681527ff01936354f43c5b49521c6c3fdc9740709976ee07acac3ebf79fbd6282cda1959060200161120d565b6001600160a01b038316158015906132f357506001600160a01b03821615155b61333f5760405162461bcd60e51b815260206004820152601d60248201527f5472616e736665722066726f6d2f746f207a65726f20616464726573730000006044820152606401610cae565b6001600160a01b0383165f908152602081905260409020548111156133765760405162461bcd60e51b8152600401610cae906141c5565b80156133a9576001600160a01b038084165f90815260208190526040808220805485900390559184168152208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611f9b91815260200190565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038516906370a0823190602401602060405180830381865afa158015613434573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061345891906141ae565b604080516003808252608082019092529192505f91906020820160608036833701905050905030815f8151811061349157613491614209565b6001600160a01b0392831660209182029290920101526025548251911690829060019081106134c2576134c2614209565b60200260200101906001600160a01b031690816001600160a01b03168152505084816002815181106134f6576134f6614209565b6001600160a01b03928316602091820292909201015260235461351c9130911686611f47565b602354604051635c11d79560e01b81526001600160a01b0390911690635c11d795906135549087905f90869030904290600401614264565b5f604051808303815f87803b15801561356b575f80fd5b505af192505050801561357c575060015b61359d576023546135989030906001600160a01b03165f611f47565b61365d565b6040516370a0823160e01b815230600482015282906001600160a01b038716906370a0823190602401602060405180830381865afa1580156135e1573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061360591906141ae565b61360f9190614303565b604080516001600160a01b0388168152602081018790529081018290529093507fa82a03c1e8613c6192a82386fbb3690070528b0dd8bcae8a5c82d9ef937d7f769060600160405180910390a15b505092915050565b801580156136805750600f5460115410806136805750601254155b156136885750565b5f8115801561369a5750601054601154115b6136a6576011546136aa565b6010545b90505f821580156136be5750601054601154115b6136ca576012546136f3565b6136f3601254601154601054816136e3576136e3614250565b04620186a002620186a091020490565b60235490915061370e9030906001600160a01b031684611f47565b60235460265460405163f305d71960e01b8152306004820152602481018590525f6044820181905260648201526001600160a01b0391821660848201524260a482015291169063f305d71990839060c40160606040518083038185885af19350505050801561379a575060408051601f3d908101601f1916820190925261379791810190614316565b60015b6137b657602354611ae09030906001600160a01b03165f611f47565b60408051848152602081018490529081018290527f947eb7d5785b0534dc368370fd3574434082455556a747116a88abea1ec6ceba9060600160405180910390a1505060118054849003905550601280548290039055505050565b5f825f0361382057505f610e77565b3082613837576021546001600160a01b0316613844565b6022546001600160a01b03165b6001600160a01b0316036139cc575f600c5411801561387d5750600c546001600160a01b0385165f908152602081905260409020548401115b156138d5576001600160a01b0384165f90815260208190526040902054600c54116138a8575f6138c5565b6001600160a01b0384165f90815260208190526040902054600c54035b9250825f036138d557505f610e77565b6138e03085856132d3565b811561393957601b805484900390556001600160a01b038085165f908152600260209081526040808320602280548616855260019190910183528184208054890190555490931682526004905220805484019055613943565b601a805484900390555b6001600160a01b0384165f9081526002602052604090205460ff166139c7576001600160a01b0384165f818152600260205260408120805460ff191660019081179091556007805491820181559091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b03191690911790555b613cdb565b5f826139da57601c546139de565b601d545b620186a08502816139f1576139f1614250565b60255491900491505f906001600160a01b031684613a1a576021546001600160a01b0316613a27565b6022546001600160a01b03165b6001600160a01b031603613ae157613a5484613a4557601e54613a49565b601f545b83620186a091020490565b90505f866001600160a01b031682617530906040515f60405180830381858888f193505050503d805f8114613aa4576040519150601f19603f3d011682016040523d82523d5f602084013e613aa9565b606091505b5050905080613abd575f9350505050610e77565b8415613ad157601f80548390039055613adb565b601e805483900390555b50613c75565b613b2d84613b08576021546001600160a01b03165f90815260066020526040902054613a49565b6022546001600160a01b03165f9081526005602052604090205483620186a091020490565b90508315613bd75760225460405163a9059cbb60e01b81526001600160a01b038881166004830152602482018490529091169063a9059cbb906044016020604051808303815f875af1925050508015613ba3575060408051601f3d908101601f19168201909252613ba0918101906141ee565b60015b613bb1575f92505050610e77565b506022546001600160a01b03165f90815260056020526040902080548290039055613c75565b60215460405163a9059cbb60e01b81526001600160a01b038881166004830152602482018490529091169063a9059cbb906044016020604051808303815f875af1925050508015613c45575060408051601f3d908101601f19168201909252613c42918101906141ee565b60015b613c53575f92505050610e77565b506021546001600160a01b03165f908152600660205260409020805482900390555b8315613cce57601d805486900390556001600160a01b038087165f908152600260209081526040808320602280548616855260019190910183528184208054870190555490931682526004905220805482019055613cd8565b601c805486900390555b50505b509092915050565b60405180606001604052805f6001600160a01b03168152602001613d05613da5565b81526020015f81525090565b600183019183908215613d99579160200282015f5b83821115613d6857835183826101000a81548162ffffff021916908362ffffff1602179055509260200192600301602081600201049283019260010302613d26565b8015613d975782816101000a81549062ffffff0219169055600301602081600201049283019260010302613d68565b505b50611565929150613dc3565b60405180606001604052806003906020820280368337509192915050565b5b80821115611565575f8155600101613dc4565b5f81518084525f5b81811015613dfb57602081850181015186830182015201613ddf565b505f602082860101526020601f19601f83011685010191505092915050565b602081525f610e776020830184613dd7565b6001600160a01b0381168114611909575f80fd5b5f8060408385031215613e51575f80fd5b8235613e5c81613e2c565b946020939093013593505050565b5f805f60608486031215613e7c575f80fd5b8335613e8781613e2c565b92506020840135613e9781613e2c565b929592945050506040919091013590565b5f60208284031215613eb8575f80fd5b8135610e7781613e2c565b8015158114611909575f80fd5b5f60208284031215613ee0575f80fd5b8135610e7781613ec3565b60c081525f613efd60c0830189613dd7565b8281036020840152613f0f8189613dd7565b60ff881660408501526001600160a01b03871660608501526080840186905283810360a08501529050613f428185613dd7565b9998505050505050505050565b5f60208284031215613f5f575f80fd5b5035919050565b803562ffffff81168114613f78575f80fd5b919050565b5f60208284031215613f8d575f80fd5b610e7782613f66565b5f8060408385031215613fa7575f80fd5b613fb083613f66565b9150613fbe60208401613f66565b90509250929050565b805f5b6003811015610e5657815162ffffff16845260209384019390910190600101613fca565b602080825282518282018190525f919060409081850190868401855b8281101561404c57815180516001600160a01b031685528681015161403188870182613fc7565b50850151608085015260a0909301929085019060010161400a565b5091979650505050505050565b634e487b7160e01b5f52604160045260245ffd5b5f805f60a0848603121561407f575f80fd5b833560ff8116811461408f575f80fd5b92506020848101356140a081613e2c565b9250605f850186136140b0575f80fd5b6040516060810181811067ffffffffffffffff821117156140d3576140d3614059565b6040528060a08701888111156140e7575f80fd5b604088015b8181101561410a576140fd81613f66565b83529184019184016140ec565b50505080925050509250925092565b5f806040838503121561412a575f80fd5b823561413581613e2c565b9150602083013561414581613e2c565b809150509250929050565b600181811c9082168061416457607f821691505b60208210810361418257634e487b7160e01b5f52602260045260245ffd5b50919050565b6020808252600c908201526b155b985d5d1a1bdc9a5e995960a21b604082015260600190565b5f602082840312156141be575f80fd5b5051919050565b6020808252600f908201526e457863656564732062616c616e636560881b604082015260600190565b5f602082840312156141fe575f80fd5b8151610e7781613ec3565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b62ffffff81811683821602808216919082811461365d5761365d61421d565b634e487b7160e01b5f52601260045260245ffd5b5f60a08201878352602087602085015260a0604085015281875180845260c0860191506020890193505f5b818110156142b45784516001600160a01b03168352938301939183019160010161428f565b50506001600160a01b03969096166060850152505050608001529392505050565b60ff841681526001600160a01b038316602082015260a081016142fb6040830184613fc7565b949350505050565b81810381811115610c7e57610c7e61421d565b5f805f60608486031215614328575f80fd5b835192506020840151915060408401519050925092509256fea2646970667358221220f610fa8ffe573fd7a1349d9e3a60cdd8e15e2a959b96eb6388f4c9d6b4a54cc564736f6c63430008180033

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.