ETH Price: $2,100.68 (-0.52%)

Token

kek (kek)
 

Overview

Max Total Supply

420,690,000,000,000 kek

Holders

4,390 (0.00%)

Transfers

-
15 ( -34.78%)

Market

Onchain Market Cap

-

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

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

OVERVIEW

kek is more than a meme.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
kekToken

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
No with 200 runs

Other Settings:
shanghai EvmVersion
// SPDX-License-Identifier: MIT

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IUniswapV2Factory} from "v2-core/interfaces/IUniswapV2Factory.sol";
import {IUniswapV2Router02} from "v2-periphery/interfaces/IUniswapV2Router02.sol";

pragma solidity ^0.8.20;

// https://kek.vip/

contract kekToken is ERC20, Ownable {
    error EthWithdrawFailed();
    error TransferingZeroAmount();
    error MaxTxAmountExceeded(uint256 maxTxAmount, uint256 amount);
    error TradingNotEnabled();
    error TradingAlreadyEnabled();
    error MaxTxOutsideRange(uint256 amount);
    error TaxOutsideRange(uint256 buyTax, uint256 sellTax);
    error NotEnoughBalance(uint256 balance, uint256 amount);

    uint8 private constant _decimals = 18;

    bool private _isSwapping = false;
    bool private _isSwapEnabled = true;
    bool private _phasesFinished = false;
    bool private _isTradingEnabled = false;

    uint256 private constant MAX_SUPPLY = 420_690 * 1e9 * 10 ** _decimals; // 420.690 trillion
    uint256 private constant MAX_SWAP = MAX_SUPPLY / 100; // 1% of total supply
    uint256 private _taxSwapThreshold = 0;

    string private constant _name = unicode"kek";
    string private constant _symbol = unicode"kek";
    string private constant _website = "https://kek.vip/";

    address private immutable _taxWallet;
    address private immutable _pair;

    address private constant UNISWAP_V2_ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
    address private constant UNISWAP_V2_FACTORY = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;
    address private constant WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

    uint256 private _swapsAllowedPerBlock = 3;
    uint256 private _buyTax = 0;
    uint256 private _sellTax = 0;
    uint256 private _maxTx = 1;
    uint256 private _startTime;

    mapping(uint256 blockNumber => uint256 swapCount) private _blockSwapCount;
    mapping(address sender => bool isExcluded) private _taxExemptions;

    receive() external payable {}

    constructor() ERC20(_name, _symbol) Ownable(msg.sender) {
        _taxWallet = msg.sender;

        _taxExemptions[msg.sender] = true;
        _taxExemptions[address(this)] = true;

        _pair = IUniswapV2Factory(UNISWAP_V2_FACTORY).createPair(address(this), WETH_ADDRESS);

        _approve(address(this), UNISWAP_V2_ROUTER, type(uint256).max);
        _mint(msg.sender, MAX_SUPPLY);
    }

    function website() public pure returns (string memory) {
        return _website;
    }

    function decimals() public pure override returns (uint8) {
        return _decimals;
    }

    /**
     * @notice Start trading. Can be called only once.
     * @notice This function will add liquidity to the pair and start trading.
     * and set the start time for the phases
     */
    function startTrading() external onlyOwner {
        if (_isTradingEnabled) revert TradingAlreadyEnabled();

        uint256 ethAmount = address(this).balance;
        uint256 tokenAmount = balanceOf(address(this));

        IUniswapV2Router02(UNISWAP_V2_ROUTER).addLiquidityETH{value: ethAmount}(
            address(this), tokenAmount, 0, 0, owner(), block.timestamp
        );

        _startTime = block.timestamp;
        _isTradingEnabled = true;
    }

    /**
     * @notice Set the maximum transaction amount as a percentage of the total supply.
     * @param maxTx The percentage of the total supply. Must be between 1 and 100.
     */
    function setMaxTransaction(uint256 maxTx) external onlyOwner {
        if (maxTx > 100 || maxTx < 1) revert MaxTxOutsideRange(maxTx);

        _maxTx = maxTx;
    }

    /**
     * @notice Set the tax rates for buying and selling. A tax rate of 100% is not allowed.
     * @param buyTax The tax rate for buying as a percentage.
     * @param sellTax The tax rate for selling as a percentage.
     */
    function setTaxes(uint256 buyTax, uint256 sellTax) external onlyOwner {
        if (buyTax >= 100 || sellTax >= 100) revert TaxOutsideRange(buyTax, sellTax);

        _buyTax = buyTax;
        _sellTax = sellTax;
    }

    /**
     * @notice Emergency withdraw tokens from the contract if you face any issues stuck tokens.
     * @param amount The amount of tokens to withdraw.
     */
    function emergencyWithdrawTokens(uint256 amount) external onlyOwner {
        super._update(address(this), _taxWallet, amount);
    }

    /**
     * @notice Emergency withdraw ETH from the contract if you face any issues stuck ETH.
     */
    function emergencyWithdraw() external onlyOwner {
        _transferEth(_taxWallet, address(this).balance);
    }

    /**
     * @notice Change the tax exemptions for a given account.
     * @param account The account to change the tax exemptions for.
     * @param isExempt Whether the account is exempt from taxes.
     */
    function changeExemptions(address account, bool isExempt) external onlyOwner {
        _taxExemptions[account] = isExempt;
    }

    /**
     * @notice Finish the phases earlier than expected.
     */
    function finishPhases() external onlyOwner {
        _phasesFinished = true;
    }

    /**
     * @notice Set the swap settings.
     * @param taxSwapThreshold The minimum balance required to activate the swapback.
     * @param swapsAllowedPerBlock The maximum number of swapbacks allowed per block.
     * @param isSwapEnabled Whether swapback is enabled.
     */
    function setSwapSettings(uint256 taxSwapThreshold, uint256 swapsAllowedPerBlock, bool isSwapEnabled)
        external
        onlyOwner
    {
        _taxSwapThreshold = taxSwapThreshold;
        _swapsAllowedPerBlock = swapsAllowedPerBlock;
        _isSwapEnabled = isSwapEnabled;
    }

    /**
     * @notice Manually force a swapback.
     * @param amount The amount of tokens to swap.
     */
    function manualSwap(uint256 amount) external onlyOwner {
        uint256 availableBalance = balanceOf(address(this));
        if (amount > availableBalance) revert NotEnoughBalance(availableBalance, amount);

        _swap(amount);
    }

    function _update(address from, address to, uint256 amount) internal override {
        if (amount == 0) revert TransferingZeroAmount();

        if (_taxExemptions[from] || _taxExemptions[to]) {
            return super._update(from, to, amount);
        }

        address pair = _pair;
        bool isBuy = from == pair;
        bool isSell = to == pair;

        _checkLimits(amount);
        _checkPhases();

        uint256 tax;
        if (isBuy) {
            tax = (amount * _buyTax) / 100;
        } else if (isSell) {
            tax = (amount * _sellTax) / 100;

            _checkSwap(amount);
        }

        if (tax > 0) {
            super._update(from, address(this), tax);
        }

        super._update(from, to, amount - tax);
    }

    /**
     * @notice Check if the transaction amount is within the allowed limits.
     * @param amount The amount of tokens being transferred.
     */
    function _checkLimits(uint256 amount) private view {
        if (!_isTradingEnabled) revert TradingNotEnabled();

        uint256 maxTxAmount = _maxTxAmount();
        if (amount > maxTxAmount) revert MaxTxAmountExceeded(maxTxAmount, amount);
    }

    /**
     * @notice Check the phases and set the tax rates for buying and selling.
     * based on the elapsed time.
     */
    function _checkPhases() private {
        if (_phasesFinished) return;

        uint256 elapsed = block.timestamp - _startTime;

        if (elapsed > 20 minutes) {
            _buyTax = 0;
            _sellTax = 0;
            _phasesFinished = true;
        } else if (elapsed > 15 minutes) {
            _buyTax = 0;
            _sellTax = 5;
        } else if (elapsed > 10 minutes) {
            _buyTax = 0;
            _sellTax = 10;
        } else if (elapsed > 5 minutes) {
            _buyTax = 5;
            _sellTax = 15;
        }
    }

    /**
     * @notice Check if the swap is allowed and if so, swap the tokens.
     * @param amount The amount of tokens to swap.
     */
    function _checkSwap(uint256 amount) private {
        if (!_isSwapEnabled) return;

        uint256 contractBalance = balanceOf(address(this));
        uint256 blockSwapCount = _blockSwapCount[block.number];

        bool isAboveThreshold = contractBalance > _taxSwapThreshold;
        bool isBelowMaxSwaps = blockSwapCount < _swapsAllowedPerBlock;

        bool isSwapAllowed = !_isSwapping && isAboveThreshold && isBelowMaxSwaps;

        if (isSwapAllowed) {
            _blockSwapCount[block.number]++;
            uint256 swapAmount = _min(amount, _min(contractBalance, MAX_SWAP));

            if (swapAmount > 0) {
                _swap(swapAmount);
            }
        }
    }

    function _swap(uint256 amount) private {
        _isSwapping = true;

        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = WETH_ADDRESS;

        IUniswapV2Router02(UNISWAP_V2_ROUTER).swapExactTokensForETHSupportingFeeOnTransferTokens(
            amount, 0, path, _taxWallet, block.timestamp
        );

        _isSwapping = false;
    }

    /**
     * @notice Transfer ETH to a given address.
     * @param to The address to transfer ETH to.
     * @param amount The amount of ETH to transfer.
     */
    function _transferEth(address to, uint256 amount) internal {
        (bool result,) = to.call{value: amount}("");
        if (!result) revert EthWithdrawFailed();
    }

    /**
     * @notice Return the maximum transaction amount.
     */
    function _maxTxAmount() private view returns (uint256) {
        uint256 maxTx = _maxTx;
        if (maxTx == 100) return MAX_SUPPLY;

        return MAX_SUPPLY * maxTx / 100;
    }

    /**
     * @notice Return the minimum of two numbers.
     * @param a The first number.
     * @param b The second number.
     * @return The minimum of the two numbers.
     */
    function _min(uint256 a, uint256 b) private pure returns (uint256) {
        return (a > b) ? b : a;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC-20
 * applications.
 */
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
    mapping(address account => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * Both values are immutable: they can only be set once during construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

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

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

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

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

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

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

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, value);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Skips emitting an {Approval} event indicating an allowance update. This is not
     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `value`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `value`.
     */
    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, value);
        _transfer(from, to, value);
        return true;
    }

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _transfer(address from, address to, uint256 value) internal {
        if (from == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        if (to == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(from, to, value);
    }

    /**
     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
     * this function.
     *
     * Emits a {Transfer} event.
     */
    function _update(address from, address to, uint256 value) internal virtual {
        if (from == address(0)) {
            // Overflow check required: The rest of the code assumes that totalSupply never overflows
            _totalSupply += value;
        } else {
            uint256 fromBalance = _balances[from];
            if (fromBalance < value) {
                revert ERC20InsufficientBalance(from, fromBalance, value);
            }
            unchecked {
                // Overflow not possible: value <= fromBalance <= totalSupply.
                _balances[from] = fromBalance - value;
            }
        }

        if (to == address(0)) {
            unchecked {
                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
                _totalSupply -= value;
            }
        } else {
            unchecked {
                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
                _balances[to] += value;
            }
        }

        emit Transfer(from, to, value);
    }

    /**
     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
     * Relies on the `_update` mechanism
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _mint(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(address(0), account, value);
    }

    /**
     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
     * Relies on the `_update` mechanism.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead
     */
    function _burn(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        _update(account, address(0), value);
    }

    /**
     * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        _approve(owner, spender, value, true);
    }

    /**
     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
     *
     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
     * `Approval` event during `transferFrom` operations.
     *
     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
     * true using the following override:
     *
     * ```solidity
     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
     *     super._approve(owner, spender, value, true);
     * }
     * ```
     *
     * Requirements are the same as {_approve}.
     */
    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
        if (owner == address(0)) {
            revert ERC20InvalidApprover(address(0));
        }
        if (spender == address(0)) {
            revert ERC20InvalidSpender(address(0));
        }
        _allowances[owner][spender] = value;
        if (emitEvent) {
            emit Approval(owner, spender, value);
        }
    }

    /**
     * @dev Updates `owner`'s allowance for `spender` based on spent `value`.
     *
     * Does not update the allowance value in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Does not emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance < type(uint256).max) {
            if (currentAllowance < value) {
                revert ERC20InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(owner, spender, currentAllowance - value, false);
            }
        }
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

pragma solidity >=0.5.0;

interface IUniswapV2Factory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint256);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint256) external view returns (address pair);
    function allPairsLength() external view returns (uint256);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}

pragma solidity >=0.6.2;

import "./IUniswapV2Router01.sol";

interface IUniswapV2Router02 is IUniswapV2Router01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountETH);
    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountETH);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable;
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC-20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

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

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;

/**
 * @dev Standard ERC-20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
 */
interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

/**
 * @dev Standard ERC-721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
     * Used in balance queries.
     * @param owner Address of the current owner of a token.
     */
    error ERC721InvalidOwner(address owner);

    /**
     * @dev Indicates a `tokenId` whose `owner` is the zero address.
     * @param tokenId Identifier number of a token.
     */
    error ERC721NonexistentToken(uint256 tokenId);

    /**
     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param tokenId Identifier number of a token.
     * @param owner Address of the current owner of a token.
     */
    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC721InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC721InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param tokenId Identifier number of a token.
     */
    error ERC721InsufficientApproval(address operator, uint256 tokenId);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC721InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC721InvalidOperator(address operator);
}

/**
 * @dev Standard ERC-1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
 */
interface IERC1155Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     * @param tokenId Identifier number of a token.
     */
    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC1155InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC1155InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param owner Address of the current owner of a token.
     */
    error ERC1155MissingApprovalForAll(address operator, address owner);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC1155InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC1155InvalidOperator(address operator);

    /**
     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
     * Used in batch transfers.
     * @param idsLength Length of the array of token identifiers
     * @param valuesLength Length of the array of token amounts
     */
    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}

pragma solidity >=0.6.2;

interface IUniswapV2Router01 {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);
    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external payable returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);
    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB);
    function removeLiquidityETH(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountToken, uint256 amountETH);
    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountA, uint256 amountB);
    function removeLiquidityETHWithPermit(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountToken, uint256 amountETH);
    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);
    function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);
    function swapExactETHForTokens(uint256 amountOutMin, address[] calldata path, address to, uint256 deadline)
        external
        payable
        returns (uint256[] memory amounts);
    function swapTokensForExactETH(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);
    function swapExactTokensForETH(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);
    function swapETHForExactTokens(uint256 amountOut, address[] calldata path, address to, uint256 deadline)
        external
        payable
        returns (uint256[] memory amounts);

    function quote(uint256 amountA, uint256 reserveA, uint256 reserveB) external pure returns (uint256 amountB);
    function getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut)
        external
        pure
        returns (uint256 amountOut);
    function getAmountIn(uint256 amountOut, uint256 reserveIn, uint256 reserveOut)
        external
        pure
        returns (uint256 amountIn);
    function getAmountsOut(uint256 amountIn, address[] calldata path)
        external
        view
        returns (uint256[] memory amounts);
    function getAmountsIn(uint256 amountOut, address[] calldata path)
        external
        view
        returns (uint256[] memory amounts);
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "v2-core/=lib/v2-core/contracts/",
    "v2-periphery/=lib/v2-periphery/contracts/"
  ],
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "shanghai",
  "viaIR": false
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"EthWithdrawFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxTxAmount","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MaxTxAmountExceeded","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MaxTxOutsideRange","type":"error"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NotEnoughBalance","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"uint256","name":"buyTax","type":"uint256"},{"internalType":"uint256","name":"sellTax","type":"uint256"}],"name":"TaxOutsideRange","type":"error"},{"inputs":[],"name":"TradingAlreadyEnabled","type":"error"},{"inputs":[],"name":"TradingNotEnabled","type":"error"},{"inputs":[],"name":"TransferingZeroAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"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":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"isExempt","type":"bool"}],"name":"changeExemptions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyWithdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finishPhases","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"manualSwap","outputs":[],"stateMutability":"nonpayable","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":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxTx","type":"uint256"}],"name":"setMaxTransaction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"taxSwapThreshold","type":"uint256"},{"internalType":"uint256","name":"swapsAllowedPerBlock","type":"uint256"},{"internalType":"bool","name":"isSwapEnabled","type":"bool"}],"name":"setSwapSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"buyTax","type":"uint256"},{"internalType":"uint256","name":"sellTax","type":"uint256"}],"name":"setTaxes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","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":"value","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":"website","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c06040525f600560146101000a81548160ff0219169083151502179055506001600560156101000a81548160ff0219169083151502179055505f600560166101000a81548160ff0219169083151502179055505f600560176101000a81548160ff0219169083151502179055505f60065560036007555f6008555f6009556001600a553480156200008f575f80fd5b50336040518060400160405280600381526020017f6b656b00000000000000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f6b656b000000000000000000000000000000000000000000000000000000000081525081600390816200010e919062001314565b50806004908162000120919062001314565b5050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160362000196575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016200018d91906200143b565b60405180910390fd5b620001a781620003e360201b60201c565b503373ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250506001600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506001600d5f3073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f73ffffffffffffffffffffffffffffffffffffffff1663c9c653963073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26040518363ffffffff1660e01b8152600401620002eb92919062001456565b6020604051808303815f875af115801562000308573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200032e9190620014b4565b73ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1681525050620003a830737a250d5630b4cf539739df2c5dacb4c659f2488d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff620004a660201b60201c565b620003dd336012600a620003bd91906200166d565b66017e9d8602b400620003d19190620016bd565b620004c060201b60201c565b62001a54565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620004bb83838360016200054a60201b60201c565b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000533575f6040517fec442f050000000000000000000000000000000000000000000000000000000081526004016200052a91906200143b565b60405180910390fd5b620005465f83836200072260201b60201c565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603620005bd575f6040517fe602df05000000000000000000000000000000000000000000000000000000008152600401620005b491906200143b565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160362000630575f6040517f94280d620000000000000000000000000000000000000000000000000000000081526004016200062791906200143b565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555080156200071c578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405162000713919062001718565b60405180910390a35b50505050565b5f81036200075c576040517f1447158500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1680620007f85750600d5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b156200081757620008118383836200095160201b60201c565b6200094c565b5f60a05190505f8173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161490505f8273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16149050620008928462000b7560201b60201c565b620008a262000c1d60201b60201c565b5f8215620008d057606460085486620008bc9190620016bd565b620008c8919062001760565b90506200090a565b81156200090957606460095486620008e99190620016bd565b620008f5919062001760565b9050620009088562000ce260201b60201c565b5b5b5f8111156200092757620009268730836200095160201b60201c565b5b62000947878783886200093b919062001797565b6200095160201b60201c565b505050505b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603620009a5578060025f828254620009989190620017d1565b9250508190555062000a76565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490508181101562000a31578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040162000a28939291906200180b565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000abf578060025f828254039250508190555062000b09565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405162000b68919062001718565b60405180910390a3505050565b600560179054906101000a900460ff1662000bbc576040517f12f1f92300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f62000bcd62000e0560201b60201c565b90508082111562000c195780826040517f23c19a2700000000000000000000000000000000000000000000000000000000815260040162000c1092919062001846565b60405180910390fd5b5050565b600560169054906101000a900460ff1662000ce0575f600b544262000c43919062001797565b90506104b081111562000c7f575f6008819055505f6009819055506001600560166101000a81548160ff02191690831515021790555062000cde565b61038481111562000c9f575f600881905550600560098190555062000cdd565b61025881111562000cbf575f600881905550600a60098190555062000cdc565b61012c81111562000cdb576005600881905550600f6009819055505b5b5b5b505b565b600560159054906101000a900460ff161562000e02575f62000d0a3062000e8860201b60201c565b90505f600c5f4381526020019081526020015f205490505f600654831190505f600754831090505f600560149054906101000a900460ff1615801562000d4d5750825b801562000d575750815b9050801562000dfc57600c5f4381526020019081526020015f205f81548092919062000d839062001871565b91905055505f62000ddd8762000dd18860646012600a62000da591906200166d565b66017e9d8602b40062000db99190620016bd565b62000dc5919062001760565b62000ecd60201b60201c565b62000ecd60201b60201c565b90505f81111562000dfa5762000df98162000ee760201b60201c565b5b505b50505050505b50565b5f80600a5490506064810362000e42576012600a62000e2591906200166d565b66017e9d8602b40062000e399190620016bd565b91505062000e85565b6064816012600a62000e5591906200166d565b66017e9d8602b40062000e699190620016bd565b62000e759190620016bd565b62000e81919062001760565b9150505b90565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b5f81831162000edd578262000edf565b815b905092915050565b6001600560146101000a81548160ff0219169083151502179055505f600267ffffffffffffffff81111562000f215762000f20620010ba565b5b60405190808252806020026020018201604052801562000f505781602001602082028036833780820191505090505b50905030815f8151811062000f6a5762000f69620018bd565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160018151811062000fd05762000fcf620018bd565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050737a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff1663791ac947835f84608051426040518663ffffffff1660e01b815260040162001063959493929190620019f2565b5f604051808303815f87803b1580156200107b575f80fd5b505af11580156200108e573d5f803e3d5ffd5b505050505f600560146101000a81548160ff0219169083151502179055505050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200112c57607f821691505b602082108103620011425762001141620010e7565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620011a67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262001169565b620011b2868362001169565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f620011fc620011f6620011f084620011ca565b620011d3565b620011ca565b9050919050565b5f819050919050565b6200121783620011dc565b6200122f620012268262001203565b84845462001175565b825550505050565b5f90565b6200124562001237565b620012528184846200120c565b505050565b5b8181101562001279576200126d5f826200123b565b60018101905062001258565b5050565b601f821115620012c857620012928162001148565b6200129d846200115a565b81016020851015620012ad578190505b620012c5620012bc856200115a565b83018262001257565b50505b505050565b5f82821c905092915050565b5f620012ea5f1984600802620012cd565b1980831691505092915050565b5f620013048383620012d9565b9150826002028217905092915050565b6200131f82620010b0565b67ffffffffffffffff8111156200133b576200133a620010ba565b5b62001347825462001114565b620013548282856200127d565b5f60209050601f8311600181146200138a575f841562001375578287015190505b620013818582620012f7565b865550620013f0565b601f1984166200139a8662001148565b5f5b82811015620013c3578489015182556001820191506020850194506020810190506200139c565b86831015620013e35784890151620013df601f891682620012d9565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6200142382620013f8565b9050919050565b620014358162001417565b82525050565b5f602082019050620014505f8301846200142a565b92915050565b5f6040820190506200146b5f8301856200142a565b6200147a60208301846200142a565b9392505050565b5f80fd5b620014908162001417565b81146200149b575f80fd5b50565b5f81519050620014ae8162001485565b92915050565b5f60208284031215620014cc57620014cb62001481565b5b5f620014db848285016200149e565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f808291508390505b60018511156200156e57808604811115620015465762001545620014e4565b5b6001851615620015565780820291505b8081029050620015668562001511565b945062001526565b94509492505050565b5f826200158857600190506200165a565b8162001597575f90506200165a565b8160018114620015b05760028114620015bb57620015f1565b60019150506200165a565b60ff841115620015d057620015cf620014e4565b5b8360020a915084821115620015ea57620015e9620014e4565b5b506200165a565b5060208310610133831016604e8410600b84101617156200162b5782820a905083811115620016255762001624620014e4565b5b6200165a565b6200163a84848460016200151d565b92509050818404811115620016545762001653620014e4565b5b81810290505b9392505050565b5f60ff82169050919050565b5f6200167982620011ca565b9150620016868362001661565b9250620016b57fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848462001577565b905092915050565b5f620016c982620011ca565b9150620016d683620011ca565b9250828202620016e681620011ca565b915082820484148315176200170057620016ff620014e4565b5b5092915050565b6200171281620011ca565b82525050565b5f6020820190506200172d5f83018462001707565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6200176c82620011ca565b91506200177983620011ca565b9250826200178c576200178b62001733565b5b828204905092915050565b5f620017a382620011ca565b9150620017b083620011ca565b9250828203905081811115620017cb57620017ca620014e4565b5b92915050565b5f620017dd82620011ca565b9150620017ea83620011ca565b9250828201905080821115620018055762001804620014e4565b5b92915050565b5f606082019050620018205f8301866200142a565b6200182f602083018562001707565b6200183e604083018462001707565b949350505050565b5f6040820190506200185b5f83018562001707565b6200186a602083018462001707565b9392505050565b5f6200187d82620011ca565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620018b257620018b1620014e4565b5b600182019050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f819050919050565b5f620019136200190d6200190784620018ea565b620011d3565b620011ca565b9050919050565b6200192581620018f3565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6200195f8162001417565b82525050565b5f62001972838362001954565b60208301905092915050565b5f602082019050919050565b5f62001996826200192b565b620019a2818562001935565b9350620019af8362001945565b805f5b83811015620019e5578151620019c9888262001965565b9750620019d6836200197e565b925050600181019050620019b2565b5085935050505092915050565b5f60a08201905062001a075f83018862001707565b62001a1660208301876200191a565b818103604083015262001a2a81866200198a565b905062001a3b60608301856200142a565b62001a4a608083018462001707565b9695505050505050565b60805160a05161249062001a845f395f6115fe01525f818161070201528181610a3a015261121401526124905ff3fe608060405260043610610138575f3560e01c806395d89b41116100aa578063beb0a4161161006e578063beb0a416146103e7578063c647b20e14610411578063db2e21bc14610439578063dd62ed3e1461044f578063ec14c0f11461048b578063f2fde38b146104b35761013f565b806395d89b4114610309578063a467aa9314610333578063a9059cbb1461035b578063ab5a188714610397578063b70143c9146103bf5761013f565b8063313ce567116100fc578063313ce567146102255780633e6df5041461024f5780636fc2508b1461027757806370a082311461028d578063715018a6146102c95780638da5cb5b146102df5761013f565b806306fdde0314610143578063095ea7b31461016d57806318160ddd146101a957806323b872dd146101d3578063293230b81461020f5761013f565b3661013f57005b5f80fd5b34801561014e575f80fd5b506101576104db565b6040516101649190611a81565b60405180910390f35b348015610178575f80fd5b50610193600480360381019061018e9190611b32565b61056b565b6040516101a09190611b8a565b60405180910390f35b3480156101b4575f80fd5b506101bd61058d565b6040516101ca9190611bb2565b60405180910390f35b3480156101de575f80fd5b506101f960048036038101906101f49190611bcb565b610596565b6040516102069190611b8a565b60405180910390f35b34801561021a575f80fd5b506102236105c4565b005b348015610230575f80fd5b506102396106ec565b6040516102469190611c36565b60405180910390f35b34801561025a575f80fd5b5061027560048036038101906102709190611c4f565b6106f4565b005b348015610282575f80fd5b5061028b61072a565b005b348015610298575f80fd5b506102b360048036038101906102ae9190611c7a565b61074f565b6040516102c09190611bb2565b60405180910390f35b3480156102d4575f80fd5b506102dd610794565b005b3480156102ea575f80fd5b506102f36107a7565b6040516103009190611cb4565b60405180910390f35b348015610314575f80fd5b5061031d6107cf565b60405161032a9190611a81565b60405180910390f35b34801561033e575f80fd5b5061035960048036038101906103549190611cf7565b61085f565b005b348015610366575f80fd5b50610381600480360381019061037c9190611b32565b610894565b60405161038e9190611b8a565b60405180910390f35b3480156103a2575f80fd5b506103bd60048036038101906103b89190611c4f565b6108b6565b005b3480156103ca575f80fd5b506103e560048036038101906103e09190611c4f565b610919565b005b3480156103f2575f80fd5b506103fb610981565b6040516104089190611a81565b60405180910390f35b34801561041c575f80fd5b5061043760048036038101906104329190611d47565b6109be565b005b348015610444575f80fd5b5061044d610a2d565b005b34801561045a575f80fd5b5061047560048036038101906104709190611d85565b610a61565b6040516104829190611bb2565b60405180910390f35b348015610496575f80fd5b506104b160048036038101906104ac9190611dc3565b610ae3565b005b3480156104be575f80fd5b506104d960048036038101906104d49190611c7a565b610b43565b005b6060600380546104ea90611e2e565b80601f016020809104026020016040519081016040528092919081815260200182805461051690611e2e565b80156105615780601f1061053857610100808354040283529160200191610561565b820191905f5260205f20905b81548152906001019060200180831161054457829003601f168201915b5050505050905090565b5f80610575610bc7565b9050610582818585610bce565b600191505092915050565b5f600254905090565b5f806105a0610bc7565b90506105ad858285610be0565b6105b8858585610c73565b60019150509392505050565b6105cc610d63565b600560179054906101000a900460ff1615610613576040517fd723eaba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f4790505f6106213061074f565b9050737a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff1663f305d7198330845f806106606107a7565b426040518863ffffffff1660e01b815260040161068296959493929190611ea0565b60606040518083038185885af115801561069e573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906106c39190611f13565b50505042600b819055506001600560176101000a81548160ff0219169083151502179055505050565b5f6012905090565b6106fc610d63565b610727307f000000000000000000000000000000000000000000000000000000000000000083610dea565b50565b610732610d63565b6001600560166101000a81548160ff021916908315150217905550565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b61079c610d63565b6107a55f611003565b565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600480546107de90611e2e565b80601f016020809104026020016040519081016040528092919081815260200182805461080a90611e2e565b80156108555780601f1061082c57610100808354040283529160200191610855565b820191905f5260205f20905b81548152906001019060200180831161083857829003601f168201915b5050505050905090565b610867610d63565b826006819055508160078190555080600560156101000a81548160ff021916908315150217905550505050565b5f8061089e610bc7565b90506108ab818585610c73565b600191505092915050565b6108be610d63565b60648111806108cd5750600181105b1561090f57806040517f0ead98430000000000000000000000000000000000000000000000000000000081526004016109069190611bb2565b60405180910390fd5b80600a8190555050565b610921610d63565b5f61092b3061074f565b9050808211156109745780826040517f8f0f420600000000000000000000000000000000000000000000000000000000815260040161096b929190611f63565b60405180910390fd5b61097d826110c6565b5050565b60606040518060400160405280601081526020017f68747470733a2f2f6b656b2e7669702f00000000000000000000000000000000815250905090565b6109c6610d63565b6064821015806109d7575060648110155b15610a1b5781816040517f827624b0000000000000000000000000000000000000000000000000000000008152600401610a12929190611f63565b60405180910390fd5b81600881905550806009819055505050565b610a35610d63565b610a5f7f00000000000000000000000000000000000000000000000000000000000000004761129f565b565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b610aeb610d63565b80600d5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055505050565b610b4b610d63565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610bbb575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610bb29190611cb4565b60405180910390fd5b610bc481611003565b50565b5f33905090565b610bdb8383836001611343565b505050565b5f610beb8484610a61565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811015610c6d5781811015610c5e578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401610c5593929190611f8a565b60405180910390fd5b610c6c84848484035f611343565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610ce3575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401610cda9190611cb4565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610d53575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401610d4a9190611cb4565b60405180910390fd5b610d5e838383611512565b505050565b610d6b610bc7565b73ffffffffffffffffffffffffffffffffffffffff16610d896107a7565b73ffffffffffffffffffffffffffffffffffffffff1614610de857610dac610bc7565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610ddf9190611cb4565b60405180910390fd5b565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610e3a578060025f828254610e2e9190611fec565b92505081905550610f08565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015610ec3578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401610eba93929190611f8a565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f4f578060025f8282540392505081905550610f99565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610ff69190611bb2565b60405180910390a3505050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6001600560146101000a81548160ff0219169083151502179055505f600267ffffffffffffffff8111156110fd576110fc61201f565b5b60405190808252806020026020018201604052801561112b5781602001602082028036833780820191505090505b50905030815f815181106111425761114161204c565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2816001815181106111a5576111a461204c565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050737a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff1663791ac947835f847f0000000000000000000000000000000000000000000000000000000000000000426040518663ffffffff1660e01b8152600401611254959493929190612130565b5f604051808303815f87803b15801561126b575f80fd5b505af115801561127d573d5f803e3d5ffd5b505050505f600560146101000a81548160ff0219169083151502179055505050565b5f8273ffffffffffffffffffffffffffffffffffffffff16826040516112c4906121b5565b5f6040518083038185875af1925050503d805f81146112fe576040519150601f19603f3d011682016040523d82523d5f602084013e611303565b606091505b505090508061133e576040517fe53e5bcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036113b3575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016113aa9190611cb4565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611423575f6040517f94280d6200000000000000000000000000000000000000000000000000000000815260040161141a9190611cb4565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550801561150c578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516115039190611bb2565b60405180910390a35b50505050565b5f810361154b576040517f1447158500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16806115e65750600d5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b156115fb576115f6838383610dea565b611718565b5f7f000000000000000000000000000000000000000000000000000000000000000090505f8173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161490505f8273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614905061168c8461171d565b6116946117b9565b5f82156116bc576064600854866116ab91906121c9565b6116b59190612237565b90506116e9565b81156116e8576064600954866116d291906121c9565b6116dc9190612237565b90506116e785611874565b5b5b5f8111156116fd576116fc873083610dea565b5b6117138787838861170e9190612267565b610dea565b505050505b505050565b600560179054906101000a900460ff16611763576040517f12f1f92300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61176c61196a565b9050808211156117b55780826040517f23c19a270000000000000000000000000000000000000000000000000000000081526004016117ac929190611f63565b60405180910390fd5b5050565b600560169054906101000a900460ff16611872575f600b54426117dc9190612267565b90506104b0811115611816575f6008819055505f6009819055506001600560166101000a81548160ff021916908315150217905550611870565b610384811115611834575f600881905550600560098190555061186f565b610258811115611852575f600881905550600a60098190555061186e565b61012c81111561186d576005600881905550600f6009819055505b5b5b5b505b565b600560159054906101000a900460ff1615611967575f6118933061074f565b90505f600c5f4381526020019081526020015f205490505f600654831190505f600754831090505f600560149054906101000a900460ff161580156118d55750825b80156118de5750815b9050801561196157600c5f4381526020019081526020015f205f8154809291906119079061229a565b91905055505f61194b876119468860646012600a6119259190612410565b66017e9d8602b40061193791906121c9565b6119419190612237565b6119df565b6119df565b90505f81111561195f5761195e816110c6565b5b505b50505050505b50565b5f80600a549050606481036119a1576012600a6119879190612410565b66017e9d8602b40061199991906121c9565b9150506119dc565b6064816012600a6119b29190612410565b66017e9d8602b4006119c491906121c9565b6119ce91906121c9565b6119d89190612237565b9150505b90565b5f8183116119ed57826119ef565b815b905092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015611a2e578082015181840152602081019050611a13565b5f8484015250505050565b5f601f19601f8301169050919050565b5f611a53826119f7565b611a5d8185611a01565b9350611a6d818560208601611a11565b611a7681611a39565b840191505092915050565b5f6020820190508181035f830152611a998184611a49565b905092915050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611ace82611aa5565b9050919050565b611ade81611ac4565b8114611ae8575f80fd5b50565b5f81359050611af981611ad5565b92915050565b5f819050919050565b611b1181611aff565b8114611b1b575f80fd5b50565b5f81359050611b2c81611b08565b92915050565b5f8060408385031215611b4857611b47611aa1565b5b5f611b5585828601611aeb565b9250506020611b6685828601611b1e565b9150509250929050565b5f8115159050919050565b611b8481611b70565b82525050565b5f602082019050611b9d5f830184611b7b565b92915050565b611bac81611aff565b82525050565b5f602082019050611bc55f830184611ba3565b92915050565b5f805f60608486031215611be257611be1611aa1565b5b5f611bef86828701611aeb565b9350506020611c0086828701611aeb565b9250506040611c1186828701611b1e565b9150509250925092565b5f60ff82169050919050565b611c3081611c1b565b82525050565b5f602082019050611c495f830184611c27565b92915050565b5f60208284031215611c6457611c63611aa1565b5b5f611c7184828501611b1e565b91505092915050565b5f60208284031215611c8f57611c8e611aa1565b5b5f611c9c84828501611aeb565b91505092915050565b611cae81611ac4565b82525050565b5f602082019050611cc75f830184611ca5565b92915050565b611cd681611b70565b8114611ce0575f80fd5b50565b5f81359050611cf181611ccd565b92915050565b5f805f60608486031215611d0e57611d0d611aa1565b5b5f611d1b86828701611b1e565b9350506020611d2c86828701611b1e565b9250506040611d3d86828701611ce3565b9150509250925092565b5f8060408385031215611d5d57611d5c611aa1565b5b5f611d6a85828601611b1e565b9250506020611d7b85828601611b1e565b9150509250929050565b5f8060408385031215611d9b57611d9a611aa1565b5b5f611da885828601611aeb565b9250506020611db985828601611aeb565b9150509250929050565b5f8060408385031215611dd957611dd8611aa1565b5b5f611de685828601611aeb565b9250506020611df785828601611ce3565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611e4557607f821691505b602082108103611e5857611e57611e01565b5b50919050565b5f819050919050565b5f819050919050565b5f611e8a611e85611e8084611e5e565b611e67565b611aff565b9050919050565b611e9a81611e70565b82525050565b5f60c082019050611eb35f830189611ca5565b611ec06020830188611ba3565b611ecd6040830187611e91565b611eda6060830186611e91565b611ee76080830185611ca5565b611ef460a0830184611ba3565b979650505050505050565b5f81519050611f0d81611b08565b92915050565b5f805f60608486031215611f2a57611f29611aa1565b5b5f611f3786828701611eff565b9350506020611f4886828701611eff565b9250506040611f5986828701611eff565b9150509250925092565b5f604082019050611f765f830185611ba3565b611f836020830184611ba3565b9392505050565b5f606082019050611f9d5f830186611ca5565b611faa6020830185611ba3565b611fb76040830184611ba3565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611ff682611aff565b915061200183611aff565b925082820190508082111561201957612018611fbf565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6120ab81611ac4565b82525050565b5f6120bc83836120a2565b60208301905092915050565b5f602082019050919050565b5f6120de82612079565b6120e88185612083565b93506120f383612093565b805f5b8381101561212357815161210a88826120b1565b9750612115836120c8565b9250506001810190506120f6565b5085935050505092915050565b5f60a0820190506121435f830188611ba3565b6121506020830187611e91565b818103604083015261216281866120d4565b90506121716060830185611ca5565b61217e6080830184611ba3565b9695505050505050565b5f81905092915050565b50565b5f6121a05f83612188565b91506121ab82612192565b5f82019050919050565b5f6121bf82612195565b9150819050919050565b5f6121d382611aff565b91506121de83611aff565b92508282026121ec81611aff565b9150828204841483151761220357612202611fbf565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61224182611aff565b915061224c83611aff565b92508261225c5761225b61220a565b5b828204905092915050565b5f61227182611aff565b915061227c83611aff565b925082820390508181111561229457612293611fbf565b5b92915050565b5f6122a482611aff565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036122d6576122d5611fbf565b5b600182019050919050565b5f8160011c9050919050565b5f808291508390505b60018511156123365780860481111561231257612311611fbf565b5b60018516156123215780820291505b808102905061232f856122e1565b94506122f6565b94509492505050565b5f8261234e5760019050612409565b8161235b575f9050612409565b8160018114612371576002811461237b576123aa565b6001915050612409565b60ff84111561238d5761238c611fbf565b5b8360020a9150848211156123a4576123a3611fbf565b5b50612409565b5060208310610133831016604e8410600b84101617156123df5782820a9050838111156123da576123d9611fbf565b5b612409565b6123ec84848460016122ed565b9250905081840481111561240357612402611fbf565b5b81810290505b9392505050565b5f61241a82611aff565b915061242583611c1b565b92506124527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461233f565b90509291505056fea2646970667358221220562b37771bbdafb8460c9cf6520688e6bf4c5da2f1a464a278adb29632599cae64736f6c63430008140033

Deployed Bytecode

0x608060405260043610610138575f3560e01c806395d89b41116100aa578063beb0a4161161006e578063beb0a416146103e7578063c647b20e14610411578063db2e21bc14610439578063dd62ed3e1461044f578063ec14c0f11461048b578063f2fde38b146104b35761013f565b806395d89b4114610309578063a467aa9314610333578063a9059cbb1461035b578063ab5a188714610397578063b70143c9146103bf5761013f565b8063313ce567116100fc578063313ce567146102255780633e6df5041461024f5780636fc2508b1461027757806370a082311461028d578063715018a6146102c95780638da5cb5b146102df5761013f565b806306fdde0314610143578063095ea7b31461016d57806318160ddd146101a957806323b872dd146101d3578063293230b81461020f5761013f565b3661013f57005b5f80fd5b34801561014e575f80fd5b506101576104db565b6040516101649190611a81565b60405180910390f35b348015610178575f80fd5b50610193600480360381019061018e9190611b32565b61056b565b6040516101a09190611b8a565b60405180910390f35b3480156101b4575f80fd5b506101bd61058d565b6040516101ca9190611bb2565b60405180910390f35b3480156101de575f80fd5b506101f960048036038101906101f49190611bcb565b610596565b6040516102069190611b8a565b60405180910390f35b34801561021a575f80fd5b506102236105c4565b005b348015610230575f80fd5b506102396106ec565b6040516102469190611c36565b60405180910390f35b34801561025a575f80fd5b5061027560048036038101906102709190611c4f565b6106f4565b005b348015610282575f80fd5b5061028b61072a565b005b348015610298575f80fd5b506102b360048036038101906102ae9190611c7a565b61074f565b6040516102c09190611bb2565b60405180910390f35b3480156102d4575f80fd5b506102dd610794565b005b3480156102ea575f80fd5b506102f36107a7565b6040516103009190611cb4565b60405180910390f35b348015610314575f80fd5b5061031d6107cf565b60405161032a9190611a81565b60405180910390f35b34801561033e575f80fd5b5061035960048036038101906103549190611cf7565b61085f565b005b348015610366575f80fd5b50610381600480360381019061037c9190611b32565b610894565b60405161038e9190611b8a565b60405180910390f35b3480156103a2575f80fd5b506103bd60048036038101906103b89190611c4f565b6108b6565b005b3480156103ca575f80fd5b506103e560048036038101906103e09190611c4f565b610919565b005b3480156103f2575f80fd5b506103fb610981565b6040516104089190611a81565b60405180910390f35b34801561041c575f80fd5b5061043760048036038101906104329190611d47565b6109be565b005b348015610444575f80fd5b5061044d610a2d565b005b34801561045a575f80fd5b5061047560048036038101906104709190611d85565b610a61565b6040516104829190611bb2565b60405180910390f35b348015610496575f80fd5b506104b160048036038101906104ac9190611dc3565b610ae3565b005b3480156104be575f80fd5b506104d960048036038101906104d49190611c7a565b610b43565b005b6060600380546104ea90611e2e565b80601f016020809104026020016040519081016040528092919081815260200182805461051690611e2e565b80156105615780601f1061053857610100808354040283529160200191610561565b820191905f5260205f20905b81548152906001019060200180831161054457829003601f168201915b5050505050905090565b5f80610575610bc7565b9050610582818585610bce565b600191505092915050565b5f600254905090565b5f806105a0610bc7565b90506105ad858285610be0565b6105b8858585610c73565b60019150509392505050565b6105cc610d63565b600560179054906101000a900460ff1615610613576040517fd723eaba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f4790505f6106213061074f565b9050737a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff1663f305d7198330845f806106606107a7565b426040518863ffffffff1660e01b815260040161068296959493929190611ea0565b60606040518083038185885af115801561069e573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906106c39190611f13565b50505042600b819055506001600560176101000a81548160ff0219169083151502179055505050565b5f6012905090565b6106fc610d63565b610727307f00000000000000000000000017834d6003fcec36640fb1ed7ee5c5aea38b39d383610dea565b50565b610732610d63565b6001600560166101000a81548160ff021916908315150217905550565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b61079c610d63565b6107a55f611003565b565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600480546107de90611e2e565b80601f016020809104026020016040519081016040528092919081815260200182805461080a90611e2e565b80156108555780601f1061082c57610100808354040283529160200191610855565b820191905f5260205f20905b81548152906001019060200180831161083857829003601f168201915b5050505050905090565b610867610d63565b826006819055508160078190555080600560156101000a81548160ff021916908315150217905550505050565b5f8061089e610bc7565b90506108ab818585610c73565b600191505092915050565b6108be610d63565b60648111806108cd5750600181105b1561090f57806040517f0ead98430000000000000000000000000000000000000000000000000000000081526004016109069190611bb2565b60405180910390fd5b80600a8190555050565b610921610d63565b5f61092b3061074f565b9050808211156109745780826040517f8f0f420600000000000000000000000000000000000000000000000000000000815260040161096b929190611f63565b60405180910390fd5b61097d826110c6565b5050565b60606040518060400160405280601081526020017f68747470733a2f2f6b656b2e7669702f00000000000000000000000000000000815250905090565b6109c6610d63565b6064821015806109d7575060648110155b15610a1b5781816040517f827624b0000000000000000000000000000000000000000000000000000000008152600401610a12929190611f63565b60405180910390fd5b81600881905550806009819055505050565b610a35610d63565b610a5f7f00000000000000000000000017834d6003fcec36640fb1ed7ee5c5aea38b39d34761129f565b565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b610aeb610d63565b80600d5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055505050565b610b4b610d63565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610bbb575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610bb29190611cb4565b60405180910390fd5b610bc481611003565b50565b5f33905090565b610bdb8383836001611343565b505050565b5f610beb8484610a61565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811015610c6d5781811015610c5e578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401610c5593929190611f8a565b60405180910390fd5b610c6c84848484035f611343565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610ce3575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401610cda9190611cb4565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610d53575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401610d4a9190611cb4565b60405180910390fd5b610d5e838383611512565b505050565b610d6b610bc7565b73ffffffffffffffffffffffffffffffffffffffff16610d896107a7565b73ffffffffffffffffffffffffffffffffffffffff1614610de857610dac610bc7565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610ddf9190611cb4565b60405180910390fd5b565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610e3a578060025f828254610e2e9190611fec565b92505081905550610f08565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015610ec3578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401610eba93929190611f8a565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f4f578060025f8282540392505081905550610f99565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610ff69190611bb2565b60405180910390a3505050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6001600560146101000a81548160ff0219169083151502179055505f600267ffffffffffffffff8111156110fd576110fc61201f565b5b60405190808252806020026020018201604052801561112b5781602001602082028036833780820191505090505b50905030815f815181106111425761114161204c565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2816001815181106111a5576111a461204c565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050737a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff1663791ac947835f847f00000000000000000000000017834d6003fcec36640fb1ed7ee5c5aea38b39d3426040518663ffffffff1660e01b8152600401611254959493929190612130565b5f604051808303815f87803b15801561126b575f80fd5b505af115801561127d573d5f803e3d5ffd5b505050505f600560146101000a81548160ff0219169083151502179055505050565b5f8273ffffffffffffffffffffffffffffffffffffffff16826040516112c4906121b5565b5f6040518083038185875af1925050503d805f81146112fe576040519150601f19603f3d011682016040523d82523d5f602084013e611303565b606091505b505090508061133e576040517fe53e5bcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036113b3575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016113aa9190611cb4565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611423575f6040517f94280d6200000000000000000000000000000000000000000000000000000000815260040161141a9190611cb4565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550801561150c578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516115039190611bb2565b60405180910390a35b50505050565b5f810361154b576040517f1447158500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16806115e65750600d5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b156115fb576115f6838383610dea565b611718565b5f7f0000000000000000000000006b4207a321319d5740d2375471953ac95d80359890505f8173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161490505f8273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614905061168c8461171d565b6116946117b9565b5f82156116bc576064600854866116ab91906121c9565b6116b59190612237565b90506116e9565b81156116e8576064600954866116d291906121c9565b6116dc9190612237565b90506116e785611874565b5b5b5f8111156116fd576116fc873083610dea565b5b6117138787838861170e9190612267565b610dea565b505050505b505050565b600560179054906101000a900460ff16611763576040517f12f1f92300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61176c61196a565b9050808211156117b55780826040517f23c19a270000000000000000000000000000000000000000000000000000000081526004016117ac929190611f63565b60405180910390fd5b5050565b600560169054906101000a900460ff16611872575f600b54426117dc9190612267565b90506104b0811115611816575f6008819055505f6009819055506001600560166101000a81548160ff021916908315150217905550611870565b610384811115611834575f600881905550600560098190555061186f565b610258811115611852575f600881905550600a60098190555061186e565b61012c81111561186d576005600881905550600f6009819055505b5b5b5b505b565b600560159054906101000a900460ff1615611967575f6118933061074f565b90505f600c5f4381526020019081526020015f205490505f600654831190505f600754831090505f600560149054906101000a900460ff161580156118d55750825b80156118de5750815b9050801561196157600c5f4381526020019081526020015f205f8154809291906119079061229a565b91905055505f61194b876119468860646012600a6119259190612410565b66017e9d8602b40061193791906121c9565b6119419190612237565b6119df565b6119df565b90505f81111561195f5761195e816110c6565b5b505b50505050505b50565b5f80600a549050606481036119a1576012600a6119879190612410565b66017e9d8602b40061199991906121c9565b9150506119dc565b6064816012600a6119b29190612410565b66017e9d8602b4006119c491906121c9565b6119ce91906121c9565b6119d89190612237565b9150505b90565b5f8183116119ed57826119ef565b815b905092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015611a2e578082015181840152602081019050611a13565b5f8484015250505050565b5f601f19601f8301169050919050565b5f611a53826119f7565b611a5d8185611a01565b9350611a6d818560208601611a11565b611a7681611a39565b840191505092915050565b5f6020820190508181035f830152611a998184611a49565b905092915050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611ace82611aa5565b9050919050565b611ade81611ac4565b8114611ae8575f80fd5b50565b5f81359050611af981611ad5565b92915050565b5f819050919050565b611b1181611aff565b8114611b1b575f80fd5b50565b5f81359050611b2c81611b08565b92915050565b5f8060408385031215611b4857611b47611aa1565b5b5f611b5585828601611aeb565b9250506020611b6685828601611b1e565b9150509250929050565b5f8115159050919050565b611b8481611b70565b82525050565b5f602082019050611b9d5f830184611b7b565b92915050565b611bac81611aff565b82525050565b5f602082019050611bc55f830184611ba3565b92915050565b5f805f60608486031215611be257611be1611aa1565b5b5f611bef86828701611aeb565b9350506020611c0086828701611aeb565b9250506040611c1186828701611b1e565b9150509250925092565b5f60ff82169050919050565b611c3081611c1b565b82525050565b5f602082019050611c495f830184611c27565b92915050565b5f60208284031215611c6457611c63611aa1565b5b5f611c7184828501611b1e565b91505092915050565b5f60208284031215611c8f57611c8e611aa1565b5b5f611c9c84828501611aeb565b91505092915050565b611cae81611ac4565b82525050565b5f602082019050611cc75f830184611ca5565b92915050565b611cd681611b70565b8114611ce0575f80fd5b50565b5f81359050611cf181611ccd565b92915050565b5f805f60608486031215611d0e57611d0d611aa1565b5b5f611d1b86828701611b1e565b9350506020611d2c86828701611b1e565b9250506040611d3d86828701611ce3565b9150509250925092565b5f8060408385031215611d5d57611d5c611aa1565b5b5f611d6a85828601611b1e565b9250506020611d7b85828601611b1e565b9150509250929050565b5f8060408385031215611d9b57611d9a611aa1565b5b5f611da885828601611aeb565b9250506020611db985828601611aeb565b9150509250929050565b5f8060408385031215611dd957611dd8611aa1565b5b5f611de685828601611aeb565b9250506020611df785828601611ce3565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680611e4557607f821691505b602082108103611e5857611e57611e01565b5b50919050565b5f819050919050565b5f819050919050565b5f611e8a611e85611e8084611e5e565b611e67565b611aff565b9050919050565b611e9a81611e70565b82525050565b5f60c082019050611eb35f830189611ca5565b611ec06020830188611ba3565b611ecd6040830187611e91565b611eda6060830186611e91565b611ee76080830185611ca5565b611ef460a0830184611ba3565b979650505050505050565b5f81519050611f0d81611b08565b92915050565b5f805f60608486031215611f2a57611f29611aa1565b5b5f611f3786828701611eff565b9350506020611f4886828701611eff565b9250506040611f5986828701611eff565b9150509250925092565b5f604082019050611f765f830185611ba3565b611f836020830184611ba3565b9392505050565b5f606082019050611f9d5f830186611ca5565b611faa6020830185611ba3565b611fb76040830184611ba3565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611ff682611aff565b915061200183611aff565b925082820190508082111561201957612018611fbf565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6120ab81611ac4565b82525050565b5f6120bc83836120a2565b60208301905092915050565b5f602082019050919050565b5f6120de82612079565b6120e88185612083565b93506120f383612093565b805f5b8381101561212357815161210a88826120b1565b9750612115836120c8565b9250506001810190506120f6565b5085935050505092915050565b5f60a0820190506121435f830188611ba3565b6121506020830187611e91565b818103604083015261216281866120d4565b90506121716060830185611ca5565b61217e6080830184611ba3565b9695505050505050565b5f81905092915050565b50565b5f6121a05f83612188565b91506121ab82612192565b5f82019050919050565b5f6121bf82612195565b9150819050919050565b5f6121d382611aff565b91506121de83611aff565b92508282026121ec81611aff565b9150828204841483151761220357612202611fbf565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61224182611aff565b915061224c83611aff565b92508261225c5761225b61220a565b5b828204905092915050565b5f61227182611aff565b915061227c83611aff565b925082820390508181111561229457612293611fbf565b5b92915050565b5f6122a482611aff565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036122d6576122d5611fbf565b5b600182019050919050565b5f8160011c9050919050565b5f808291508390505b60018511156123365780860481111561231257612311611fbf565b5b60018516156123215780820291505b808102905061232f856122e1565b94506122f6565b94509492505050565b5f8261234e5760019050612409565b8161235b575f9050612409565b8160018114612371576002811461237b576123aa565b6001915050612409565b60ff84111561238d5761238c611fbf565b5b8360020a9150848211156123a4576123a3611fbf565b5b50612409565b5060208310610133831016604e8410600b84101617156123df5782820a9050838111156123da576123d9611fbf565b5b612409565b6123ec84848460016122ed565b9250905081840481111561240357612402611fbf565b5b81810290505b9392505050565b5f61241a82611aff565b915061242583611c1b565b92506124527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461233f565b90509291505056fea2646970667358221220562b37771bbdafb8460c9cf6520688e6bf4c5da2f1a464a278adb29632599cae64736f6c63430008140033

Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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