ETH Price: $3,355.65 (-1.85%)

Token

Taopad (TPAD)
 

Overview

Max Total Supply

1,000,000 TPAD

Holders

2,295 (0.00%)

Market

Price

$0.07 @ 0.000022 ETH (+1.95%)

Onchain Market Cap

$74,550.00

Circulating Supply Market Cap

$0.00

Other Info

Token Contract (WITH 18 Decimals)

Filtered by Token Holder
sybilian.eth
Balance
140.454392370497258943 TPAD

Value
$10.47 ( ~0.00312010937611231 Eth) [0.0140%]
0x08c4e146e9e0935c627049cc21dfefbe9e384004
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

TaoPad offers innovative rewards via validator nodes, miners and its launchpad. This synergy enhances $TAO's value, incentivizing participation and fueling decentralized AI and blockchain growth, benefiting $TPAD holders through $wTAO rewards.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Taopad

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-12-14
*/

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;

// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

// OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol)

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

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

// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)

// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
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);
}

// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)

/**
 * @dev Interface for the optional metadata functions from the ERC20 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);
}

// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)

/**
 * @dev Standard ERC20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 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 ERC721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-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 ERC1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 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);
}

/**
 * @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 ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 */
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}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual 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}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * 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:
     * ```
     * 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);
            }
        }
    }
}

// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)

// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20Metadata.sol)

// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)

// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * ==== Security Considerations
 *
 * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
 * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
 * considered as an intention to spend the allowance in any specific way. The second is that because permits have
 * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
 * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
 * generally recommended is:
 *
 * ```solidity
 * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
 *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
 *     doThing(..., value);
 * }
 *
 * function doThing(..., uint256 value) public {
 *     token.safeTransferFrom(msg.sender, address(this), value);
 *     ...
 * }
 * ```
 *
 * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
 * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
 * {SafeERC20-safeTransferFrom}).
 *
 * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
 * contracts should have entry points that don't rely on permit.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     *
     * CAUTION: See Security Considerations above.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error AddressInsufficientBalance(address account);

    /**
     * @dev There's no code at `target` (it is not a contract).
     */
    error AddressEmptyCode(address target);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedInnerCall();

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        if (address(this).balance < amount) {
            revert AddressInsufficientBalance(address(this));
        }

        (bool success, ) = recipient.call{value: amount}("");
        if (!success) {
            revert FailedInnerCall();
        }
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason or custom error, it is bubbled
     * up by this function (like regular Solidity function calls). However, if
     * the call reverted with no returned reason, this function reverts with a
     * {FailedInnerCall} error.
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert AddressInsufficientBalance(address(this));
        }
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
     * unsuccessful call.
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata
    ) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            // only check if target is a contract if the call was successful and the return data is empty
            // otherwise we already know that it was a contract
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
     * revert reason or with a default {FailedInnerCall} error.
     */
    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            return returndata;
        }
    }

    /**
     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
     */
    function _revert(bytes memory returndata) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert FailedInnerCall();
        }
    }
}

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    /**
     * @dev An operation with an ERC20 token failed.
     */
    error SafeERC20FailedOperation(address token);

    /**
     * @dev Indicates a failed `decreaseAllowance` request.
     */
    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        forceApprove(token, spender, oldAllowance + value);
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
     * value, non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
        unchecked {
            uint256 currentAllowance = token.allowance(address(this), spender);
            if (currentAllowance < requestedDecrease) {
                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
            }
            forceApprove(token, spender, currentAllowance - requestedDecrease);
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data);
        if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
    }
}

// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol)

/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys a `value` amount of tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 value) public virtual {
        _burn(_msgSender(), value);
    }

    /**
     * @dev Destroys a `value` amount of tokens from `account`, deducting from
     * the caller's allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `value`.
     */
    function burnFrom(address account, uint256 value) public virtual {
        _spendAllowance(account, _msgSender(), value);
        _burn(account, value);
    }
}

// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant NOT_ENTERED = 1;
    uint256 private constant ENTERED = 2;

    uint256 private _status;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    constructor() {
        _status = NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

        // Any calls to nonReentrant after this point will fail
        _status = ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

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

    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(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

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

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

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

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

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

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

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

pragma abicoder v2;

/// @title Callback for IUniswapV3PoolActions#swap
/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface
interface IUniswapV3SwapCallback {
    /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.
    /// @dev In the implementation you must pay the pool tokens owed for the swap.
    /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.
    /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.
    /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by
    /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.
    /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by
    /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.
    /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call
    function uniswapV3SwapCallback(
        int256 amount0Delta,
        int256 amount1Delta,
        bytes calldata data
    ) external;
}

/// @title Router token swapping functionality
/// @notice Functions for swapping tokens via Uniswap V3
interface ISwapRouter is IUniswapV3SwapCallback {
    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 sqrtPriceLimitX96;
    }

    /// @notice Swaps `amountIn` of one token for as much as possible of another token
    /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata
    /// @return amountOut The amount of the received token
    function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);

    struct ExactInputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
    }

    /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path
    /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata
    /// @return amountOut The amount of the received token
    function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);

    struct ExactOutputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
        uint160 sqrtPriceLimitX96;
    }

    /// @notice Swaps as little as possible of one token for `amountOut` of another token
    /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata
    /// @return amountIn The amount of the input token
    function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);

    struct ExactOutputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
    }

    /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)
    /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata
    /// @return amountIn The amount of the input token
    function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);
}

/// @title ERC20 rewards
/// @author @niera26
/// @notice buy and sell tax on this token with rewardToken as rewards
/// @notice source: https://github.com/niera26/erc20-rewards-contracts
contract ERC20Rewards is Ownable, ERC20, ERC20Burnable, ReentrancyGuard {
    using SafeERC20 for IERC20;
    using SafeERC20 for IERC20Metadata;

    // =========================================================================
    // dependencies.
    // =========================================================================

    ISwapRouter public constant swapRouter = ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
    IUniswapV2Router02 public constant router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
    IERC20Metadata public constant rewardToken = IERC20Metadata(0x77E06c9eCCf2E797fd462A92B6D7642EF85b0A44); // wTAO

    // =========================================================================
    // rewards management.
    // =========================================================================

    // numerator multiplier so tokenPerShare does not get rounded to 0.
    uint256 private constant PRECISION = 1e18;

    // scale factor so reward token scales to 18 decimals.
    uint256 private immutable SCALE_FACTOR;

    // the accumulated amount of reward token per share.
    uint256 private tokenPerShare;

    // total shares of this token.
    // (different from total supply because of fees and excluded wallets).
    uint256 public totalShares;

    // shareholders record.
    // (non excluded addresses are updated after they send/receive tokens).
    mapping(address => Share) private shareholders;

    struct Share {
        uint256 amount; // recorded balance after last transfer.
        uint256 earned; // amount of tokens earned but not claimed yet.
        uint256 tokenPerShareLast; // token per share value of the last earn occurrence.
    }

    // total amount of reward tokens ever claimed by holders.
    uint256 public totalRewardClaimed;

    // total amount of reward tokens ever distributed.
    uint256 public totalRewardDistributed;

    // amm pair addresses the tranfers from/to are taxed.
    // (populated with WETH/this token pair address in the constructor).
    mapping(address => bool) public pairs;

    // contract addresses that opted in for rewards.
    mapping(address => bool) public isOptin;

    // =========================================================================
    // reward donations.
    // =========================================================================

    // the number of reward tokens to emit per block.
    uint256 public rewardTokenPerBlock;

    // the amout of reward tokens already emitted.
    uint256 public emittedRewardsAcc;

    // last block reward tokens has been emitted.
    uint256 public lastEmittingBlock;

    // =========================================================================
    // operator address.
    // =========================================================================

    // the operator address receive marketing tax and can set non critical
    // settings. Allows to renounce ownership of critical settings. It is the
    // same as the owner by default and receive marketing tax. It can:
    // - update itself.
    // - set uniswap V3 pool fee setting.
    // - set the reward token per block rate.
    address public operator;

    // =========================================================================
    // anti-bot and limitations.
    // =========================================================================

    mapping(address => bool) public isBlacklisted;

    uint256 public maxWallet = type(uint256).max; // set to 1% in initialize
    uint256 public startBlock = 0;
    uint8 public deadBlocks = 1;

    // =========================================================================
    // pool options.
    // =========================================================================

    uint24 public poolFee = 10000; // works for wTAO

    // =========================================================================
    // fees.
    // =========================================================================

    uint24 public constant maxSwapFee = 3000;
    uint24 public constant maxMarketingFee = 8000;
    uint24 public constant feeDenominator = 10000;

    uint24 public buyFee = 2400;
    uint24 public sellFee = 2400;
    uint24 public marketingFee = 8000;

    // =========================================================================
    // events.
    // =========================================================================

    event OptIn(address addr);
    event OptOut(address addr);
    event AddToBlacklist(address addr);
    event RemoveFromBlacklist(address addr);
    event Claim(address indexed addr, address indexed to, uint256 amount);
    event Distribute(address indexed addr, uint256 amount);
    event Sweep(address indexed addr, address indexed token, uint256 amount);

    // =========================================================================
    // modifiers.
    // =========================================================================

    modifier onlyOperator() {
        require(msg.sender == operator, "!operator");
        _;
    }

    // =========================================================================
    // constructor.
    // =========================================================================

    constructor(string memory name, string memory symbol, uint256 _totalSupply)
        Ownable(msg.sender)
        ERC20(name, symbol)
    {
        // operator is deployer by default.
        operator = msg.sender;

        // set the reward token scale factor.
        uint8 rewardTokenDecimals = rewardToken.decimals();

        require(rewardTokenDecimals <= 18, "reward token decimals must be <= 18");

        SCALE_FACTOR = 10 ** (18 - rewardTokenDecimals);

        // mint total supply to itself.
        _mint(address(this), _totalSupply * 10 ** decimals());
    }

    // =========================================================================
    // exposed contract values.
    // =========================================================================

    /**
     * Return the remaining rewards === reward balance - emitted rewards.
     */
    function remainingRewards() public view returns (uint256) {
        return rewardBalance() - emittedRewards();
    }

    /**
     * Return the reward balance === balance - what's remaining to claim.
     *
     * It is the amount that can be emitted in total.
     */
    function rewardBalance() public view returns (uint256) {
        uint256 amountToClaim = totalRewardDistributed - totalRewardClaimed;

        return rewardToken.balanceOf(address(this)) - amountToClaim;
    }

    /**
     * Return the amount of emitted reward since the last block rewards has
     * been emitted, according to the reward token per block.
     */
    function emittedRewards() public view returns (uint256) {
        if (lastEmittingBlock == 0) return 0;
        if (rewardTokenPerBlock == 0) return 0;

        uint256 balance = rewardBalance();

        if (balance == 0) return 0;

        uint256 emitted = emittedRewardsAcc + (rewardTokenPerBlock * (block.number - lastEmittingBlock));

        return emitted < balance ? emitted : balance;
    }

    /**
     * Return the amount of reward tokens the given address can claim.
     */
    function pendingRewards(address addr) external view returns (uint256) {
        return _pendingRewards(shareholders[addr]);
    }

    // =========================================================================
    // exposed user functions.
    // =========================================================================

    /**
     * Claim reward tokens and send them to given address.
     */
    function claim(address to) external nonReentrant {
        Share storage share = shareholders[msg.sender];

        _earn(share);

        uint256 amountToClaim = share.earned;

        if (amountToClaim == 0) return;

        share.earned = 0;

        totalRewardClaimed += amountToClaim;

        rewardToken.safeTransfer(to, amountToClaim);

        emit Claim(msg.sender, to, amountToClaim);
    }

    /**
     * Create a pair between this token and the given token.
     */
    function createAmmPairWith(address token) public {
        IUniswapV2Factory factory = IUniswapV2Factory(router.factory());

        address pair = factory.createPair(token, address(this));

        pairs[pair] = true;
    }

    /**
     * Register an existing pair between this token and the given token.
     */
    function recordAmmPairWith(address token) public {
        IUniswapV2Factory factory = IUniswapV2Factory(router.factory());

        address pair = factory.getPair(token, address(this));

        pairs[pair] = true;
    }

    /**
     * Optin for rewards when you are excluded from rewards (contracts).
     */
    function rewardOptin() external {
        _includeToRewards(msg.sender);

        isOptin[msg.sender] = true;

        emit OptIn(msg.sender);
    }

    /**
     * Optout for rewards when you are included to rewards (contracts).
     */
    function rewardOptout() external {
        _removeFromRewards(msg.sender);

        isOptin[msg.sender] = false;

        emit OptOut(msg.sender);
    }

    /**
     * Swap the collected tax to ETH.
     *
     * Pass minimal expected amount to prevent slippage/frontrun.
     */
    function swapCollectedTax(uint256 amountOutMin) public {
        // return if no tax collected.
        uint256 amountIn = balanceOf(address(this));

        if (amountIn == 0) return;

        // swap tax to eth.
        uint256 collectedEth = _swapTokenToETHV2(address(this), amountIn, amountOutMin);

        // collect marketing tax.
        uint256 marketingAmount = (collectedEth * marketingFee) / feeDenominator;

        if (marketingAmount > 0) {
            payable(operator).transfer(marketingAmount);
        }
    }

    /**
     * Distribute reward token.
     *
     * Pass minimal expected amount to prevent slippage/frontrun.
     */
    function distribute(uint256 amountOutMinimum) public {
        if (totalShares == 0) return;

        // distribute the rewards that was emitted since last update.
        uint256 amountToDistribute = emittedRewards();

        // swap eth balance to reward token and add it to amount to distribute.
        uint256 amountIn = address(this).balance;

        if (amountIn > 0) {
            amountToDistribute += _swapETHToRewardV3(address(this), amountIn, amountOutMinimum);
        }

        // stop when no rewards.
        if (amountToDistribute == 0) return;

        // distribute rewards.
        tokenPerShare += (amountToDistribute * SCALE_FACTOR * PRECISION) / totalShares;
        totalRewardDistributed += amountToDistribute;

        // reset emitted rewards.
        emittedRewardsAcc = 0;
        lastEmittingBlock = block.number;

        emit Distribute(msg.sender, amountToDistribute);
    }

    /**
     * Sweep any other ERC20 mistakenly sent to this contract.
     */
    function sweep(IERC20 otherToken) external {
        require(address(otherToken) != address(this), "!sweep");
        require(address(otherToken) != address(rewardToken), "!sweep");

        uint256 amount = otherToken.balanceOf(address(this));

        otherToken.safeTransfer(msg.sender, amount);

        emit Sweep(msg.sender, address(otherToken), amount);
    }

    // =========================================================================
    // exposed admin functions.
    // =========================================================================

    /**
     * Send initial allocations before trading started.
     */
    function allocate(address to, uint256 amount) external onlyOwner {
        require(startBlock == 0, "!initialized");

        this.transfer(to, amount);
    }

    /**
     * Remove max wallet limits, one shoot.
     */
    function removeLimits() external onlyOwner {
        maxWallet = type(uint256).max;
    }

    /**
     * Set the fees.
     */
    function setFee(uint24 _buyFee, uint24 _sellFee, uint24 _marketingFee) external onlyOwner {
        require(_buyFee <= maxSwapFee, "!buyFee");
        require(_sellFee <= maxSwapFee, "!sellFee");
        require(_marketingFee <= maxMarketingFee, "!marketingFee");

        buyFee = _buyFee;
        sellFee = _sellFee;
        marketingFee = _marketingFee;
    }

    /**
     * Remove the given address from the blacklist.
     */
    function removeFromBlacklist(address addr) external onlyOwner {
        _removeFromBlacklist(addr);
    }

    /**
     * Initialize the trading with the given eth and this contract balance.
     *
     * Starts trading, sets max wallet to 1% of the supply, create the uniswap V2 pair
     * with ETH, adds liquidity.
     *
     * LP tokens are sent to owner.
     */
    function initialize() external payable onlyOwner {
        require(msg.value > 0, "!liquidity");
        require(startBlock == 0, "!initialized");

        // start deadblocks from there.
        startBlock = block.number;

        // init max wallet to 1%.
        maxWallet = totalSupply() / 100;

        // the all balance will be put in the LP.
        uint256 balance = balanceOf(address(this));

        // create an amm pair with WETH.
        // as a contract, pair is automatically excluded from rewards.
        createAmmPairWith(router.WETH());

        // approve router to use total balance.
        _approve(address(this), address(router), balance);

        // add liquidity and send LP to owner.
        router.addLiquidityETH{value: msg.value}(address(this), balance, 0, 0, msg.sender, block.timestamp);
    }

    // =========================================================================
    // exposed operator functions.
    // =========================================================================

    /**
     * Operator can update itself.
     */
    function setOperator(address _operator) external onlyOperator {
        require(address(0) != _operator, "!address");
        operator = _operator;
    }

    /**
     * Set the uniswap V3 pool fee.
     */
    function setPoolFee(uint24 _poolFee) external onlyOperator {
        poolFee = _poolFee;
    }

    /**
     * Set the reward token per block. Accumulates the emitted rewards until this
     * block before updating the value.
     */
    function setRewardTokenPerBlock(uint256 _rewardTokenPerBlock) external onlyOperator {
        emittedRewardsAcc = emittedRewards();
        rewardTokenPerBlock = _rewardTokenPerBlock;
        lastEmittingBlock = block.number;
    }

    /**
     * Set the reward token per block without accumulating what has been
     * emitted. Fallback is case of an error.
     */
    function setRewardTokenPerBlockUnsafe(uint256 _rewardTokenPerBlock) external onlyOperator {
        rewardTokenPerBlock = _rewardTokenPerBlock;
    }

    /**
     * Empty the emitted rewards. Fallback in case of error.
     */
    function resetEmittedRewardsUnsafe() external onlyOperator {
        emittedRewardsAcc = 0;
    }

    // =========================================================================
    // internal functions.
    // =========================================================================

    /**
     * Return whether current block is a dead block (= blacklisted when buying in a dead block).
     */
    function _isDeadBlock() private view returns (bool) {
        return block.number <= startBlock + deadBlocks;
    }

    /**
     * Return addresses excluded from max wallet limit (= this contract, router or pairs).
     *
     * Blacklisted addresses are excluded too so they can buy as much as they want.
     */
    function _isExcludedFromMaxWallet(address addr) private view returns (bool) {
        return address(this) == addr || address(router) == addr || pairs[addr] || isBlacklisted[addr];
    }

    /**
     * Return adresses excluded from taxes (= this contract or router).
     */
    function _isExcludedFromTaxes(address addr) private view returns (bool) {
        return address(this) == addr || address(router) == addr;
    }

    /**
     * Retrun addresses excluded from rewards.
     *
     * - addresses of contracts that didn't opted in for rewards.
     * - blacklisted addresses.
     * - zero address to save gas on mint/burn (its balance is always 0 so it would never get shares anyway)
     * - this contract address is removed too because address(this).code.length == 0 in the constructor.
     * - remove dead address because people are used to it.
     */
    function _isExcludedFromRewards(address addr) private view returns (bool) {
        return address(0) == addr || address(this) == addr || (addr.code.length > 0 && !isOptin[addr])
            || isBlacklisted[addr] || 0x000000000000000000000000000000000000dEaD == addr;
    }

    /**
     * Add the given address to blacklist.
     */
    function _addToBlacklist(address addr) private {
        _removeFromRewards(addr);

        isBlacklisted[addr] = true;

        emit AddToBlacklist(addr);
    }

    /**
     * Remove the given address from blacklist.
     */
    function _removeFromBlacklist(address addr) private {
        _includeToRewards(addr);

        isBlacklisted[addr] = false;

        emit RemoveFromBlacklist(addr);
    }

    /**
     * Include the given address to rewards. Should only concern:
     *
     * - addresses of contracts opting in for rewards.
     * - addresses being removed from blacklist.
     */
    function _includeToRewards(address addr) private {
        // ensure we dont update total shares twice.
        if (!_isExcludedFromRewards(addr)) return;

        // update total shares.
        uint256 balance = balanceOf(addr);

        totalShares += balance;

        // restart earning from now.
        Share storage share = shareholders[addr];

        share.amount = balance;
        share.tokenPerShareLast = tokenPerShare;
    }

    /**
     * Remove the given address from rewards. Should only concern:
     *
     * - addresses of contracts opting out of rewards.
     * - addresses being added to blacklist.
     */
    function _removeFromRewards(address addr) private {
        // ensure we dont update total shares twice.
        if (_isExcludedFromRewards(addr)) return;

        // update total shares.
        totalShares -= balanceOf(addr);

        // make sure pending rewards are earned and stop earning (share.amount = 0)
        Share storage share = shareholders[addr];

        _earn(share);

        share.amount = 0;
    }

    /**
     * Compute the pending rewards of the given share.
     *
     * The rewards earned since the last transfer are added to the already earned
     * rewards.
     */
    function _pendingRewards(Share memory share) private view returns (uint256) {
        uint256 RDiff = tokenPerShare - share.tokenPerShareLast;
        uint256 earned = (share.amount * RDiff) / (SCALE_FACTOR * PRECISION);

        return share.earned + earned;
    }

    /**
     * Earn the rewards of the given share.
     */
    function _earn(Share storage share) private {
        uint256 pending = _pendingRewards(share);

        share.earned = pending;
        share.tokenPerShareLast = tokenPerShare;
    }

    /**
     * Override the update method in order to take fee when transfer is from/to
     * a registered amm pair.
     *
     * - transfers from/to registered pairs are taxed.
     * - addresses buying in a deadblock are blacklisted and cant transfer tokens anymore.
     * - prevents receiving address to get more than max wallet.
     * - taxed tokens are sent to this very contract.
     * - on a taxed sell, the collected tax is swapped for eth.
     * - updates the shares of both the from and to addresses.
     */
    function _update(address from, address to, uint256 amount) internal override {
        // blacklisted addresses cant transfer tokens.
        require(!isBlacklisted[from], "blacklisted");

        // check if it is a taxed buy or sell.
        bool isTaxedBuy = pairs[from] && !_isExcludedFromTaxes(to);
        bool isTaxedSell = !_isExcludedFromTaxes(from) && pairs[to];

        // take the fee if it is a buy or sell.
        uint256 fee = (isTaxedBuy ? buyFee : 0) + (isTaxedSell ? sellFee : 0);

        uint256 taxAmount = (amount * fee) / feeDenominator;

        uint256 actualTransferAmount = amount - taxAmount;

        // add to blacklist while buying in dead block.
        if (isTaxedBuy && _isDeadBlock()) {
            _addToBlacklist(to);
        }

        // prevents max wallet for regular addresses.
        if (!_isExcludedFromMaxWallet(to)) {
            require(actualTransferAmount + balanceOf(to) <= maxWallet, "!maxWallet");
        }

        // transfer the tax to this contract if any.
        if (taxAmount > 0) {
            super._update(from, address(this), taxAmount);
        }

        // swaps the tax to eth if it is a taxed sell.
        if (isTaxedSell) {
            swapCollectedTax(0);
        }

        // transfer the actual amount.
        super._update(from, to, actualTransferAmount);

        // updates shareholders values.
        _updateShare(from);
        _updateShare(to);
    }

    /**
     * Update the total shares and the shares of the given address if it is not
     * excluded from rewards.
     *
     * Earn first with his current share amount then update shares according to
     * its new balance.
     */
    function _updateShare(address addr) private {
        if (_isExcludedFromRewards(addr)) return;

        uint256 balance = balanceOf(addr);

        Share storage share = shareholders[addr];

        totalShares = totalShares - share.amount + balance;

        _earn(share);

        share.amount = balance;
    }

    /**
     * Swap amount of this token for ETH to address and return the amount received.
     */
    function _swapTokenToETHV2(address to, uint256 amountIn, uint256 amountOutMin) private returns (uint256) {
        // return 0 if no amount given.
        if (amountIn == 0) return 0;

        // approve router to spend tokens.
        _approve(address(this), address(router), amountIn);

        // swap the whole amount to eth.
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = router.WETH();

        uint256 originalETHbalance = address(this).balance;

        router.swapExactTokensForETHSupportingFeeOnTransferTokens(amountIn, amountOutMin, path, to, block.timestamp);

        return address(this).balance - originalETHbalance;
    }

    /**
     * Swap amount of ETH for reward tokens to address and return the amount received.
     */
    function _swapETHToRewardV3(address to, uint256 amountIn, uint256 amountOutMinimum) private returns (uint256) {
        // return 0 if no amount given.
        if (amountIn == 0) return 0;

        // build the swap parameter.
        ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
            tokenIn: router.WETH(),
            tokenOut: address(rewardToken),
            fee: poolFee,
            recipient: to,
            deadline: block.timestamp,
            amountIn: amountIn,
            amountOutMinimum: amountOutMinimum,
            sqrtPriceLimitX96: 0
        });

        // execute the swap and return the number of received tokens.
        return swapRouter.exactInputSingle{value: amountIn}(params);
    }

    receive() external payable {}
}

/**
 * Useful Links:
 * 
 * Website: https://taopad.io/
 * X: https://x.com/TaoPadX
 * 
 * Expanding The Tao Ecosystem.
 * $TAOPAD holders receive $wTAO
 * 
 *
 */

/// @title Taopad
/// @author @niera26
/// @notice buy and sell tax on this token with rewardToken as wTao
/// @notice source: https://github.com/taopad/taopad-contracts
contract Taopad is ERC20Rewards {
    constructor() ERC20Rewards("Taopad", "TPAD", 1e6) {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"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":"FailedInnerCall","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":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"AddToBlacklist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Distribute","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"OptIn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"OptOut","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":false,"internalType":"address","name":"addr","type":"address"}],"name":"RemoveFromBlacklist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Sweep","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":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"allocate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"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":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"buyFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"createAmmPairWith","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deadBlocks","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emittedRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emittedRewardsAcc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeDenominator","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isOptin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastEmittingBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketingFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMarketingFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSwapFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pairs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"pendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"recordAmmPairWith","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"remainingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"removeFromBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"removeLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetEmittedRewardsUnsafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardOptin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardOptout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardTokenPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint24","name":"_buyFee","type":"uint24"},{"internalType":"uint24","name":"_sellFee","type":"uint24"},{"internalType":"uint24","name":"_marketingFee","type":"uint24"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"_poolFee","type":"uint24"}],"name":"setPoolFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardTokenPerBlock","type":"uint256"}],"name":"setRewardTokenPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardTokenPerBlock","type":"uint256"}],"name":"setRewardTokenPerBlockUnsafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"}],"name":"swapCollectedTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapRouter","outputs":[{"internalType":"contract ISwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"otherToken","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRewardClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRewardDistributed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"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"},{"stateMutability":"payable","type":"receive"}]

60a06040526000196013556000601455601580546001600160681b0319166b1f40000960000960002710011790553480156200003a57600080fd5b50604080518082018252600681526515185bdc185960d21b602080830191909152825180840190935260048352631514105160e21b9083015290620f424082823380620000a257604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000ad8162000210565b506004620000bc838262000d54565b506005620000cb828262000d54565b5050600160065550601180546001600160a01b031916331790556040805163313ce56760e01b815290516000917377e06c9eccf2e797fd462a92b6d7642ef85b0a449163313ce567916004808201926020929091908290030181865afa1580156200013a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000160919062000e20565b905060128160ff161115620001c45760405162461bcd60e51b815260206004820152602360248201527f72657761726420746f6b656e20646563696d616c73206d757374206265203c3d60448201526204062760eb1b606482015260840162000099565b620001d181601262000e5b565b620001de90600a62000f74565b6080526200020630620001f46012600a62000f74565b62000200908562000f85565b62000260565b50505050620010ca565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0382166200028c5760405163ec442f0560e01b81526000600482015260240162000099565b6200029a600083836200029e565b5050565b6001600160a01b03831660009081526012602052604090205460ff1615620002f75760405162461bcd60e51b815260206004820152600b60248201526a189b1858dadb1a5cdd195960aa1b604482015260640162000099565b6001600160a01b0383166000908152600c602052604081205460ff1680156200032857506200032683620004d1565b155b905060006200033785620004d1565b1580156200035d57506001600160a01b0384166000908152600c602052604090205460ff165b90506000816200036f57600062000383565b601554670100000000000000900462ffffff165b8362000391576000620003a2565b601554640100000000900462ffffff165b620003ae919062000f9f565b62ffffff1690506000612710620003c6838762000f85565b620003d2919062000fc5565b90506000620003e2828762000fe8565b9050848015620003f75750620003f762000508565b15620004085762000408876200052a565b62000413876200058f565b6200047d576013546001600160a01b03881660009081526001602052604090205462000440908362000ffe565b11156200047d5760405162461bcd60e51b815260206004820152600a602482015269085b585e15d85b1b195d60b21b604482015260640162000099565b81156200049157620004918830846200060a565b8315620004a457620004a460006200073d565b620004b18888836200060a565b620004bc88620007ed565b620004c787620007ed565b5050505050505050565b6000306001600160a01b038316148062000502575060008051602062003d808339815191526001600160a01b038316145b92915050565b601554601454600091620005229160ff9091169062000ffe565b431115905090565b620005358162000855565b6001600160a01b038116600081815260126020908152604091829020805460ff1916600117905590519182527f6b713f4f12b0a0860e4b6b54d27ef8de95da632b1250f5c12f8254fdedbc2ebd910160405180910390a150565b6000306001600160a01b0383161480620005c0575060008051602062003d808339815191526001600160a01b038316145b80620005e457506001600160a01b0382166000908152600c602052604090205460ff165b80620005025750506001600160a01b031660009081526012602052604090205460ff1690565b6001600160a01b038316620006395780600360008282546200062d919062000ffe565b90915550620006ad9050565b6001600160a01b038316600090815260016020526040902054818110156200068e5760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640162000099565b6001600160a01b03841660009081526001602052604090209082900390555b6001600160a01b038216620006cb57600380548290039055620006ea565b6001600160a01b03821660009081526001602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516200073091815260200190565b60405180910390a3505050565b30600090815260016020526040812054908190036200075a575050565b600062000769308385620008c4565b6015549091506000906127109062000795906a0100000000000000000000900462ffffff168462000f85565b620007a1919062000fc5565b90508015620007e7576011546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015620007e5573d6000803e3d6000fd5b505b50505050565b620007f88162000a7a565b15620008015750565b6001600160a01b038116600090815260016020908152604080832054600990925290912080546008548391620008379162000fe8565b62000843919062000ffe565b600855620008518162000b12565b5550565b620008608162000a7a565b15620008695750565b6001600160a01b0381166000908152600160205260409020546008600082825462000895919062000fe8565b90915550506001600160a01b0381166000908152600960205260409020620008bd8162000b12565b6000905550565b600082600003620008d85750600062000a73565b620008f43060008051602062003d808339815191528562000b55565b60408051600280825260608201835260009260208301908036833701905050905030816000815181106200092c576200092c62001014565b60200260200101906001600160a01b031690816001600160a01b03168152505060008051602062003d808339815191526001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200099a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620009c091906200102a565b81600181518110620009d657620009d662001014565b6001600160a01b039092166020928302919091019091015260405163791ac94760e01b8152479060008051602062003d808339815191529063791ac9479062000a2c908890889087908c90429060040162001055565b600060405180830381600087803b15801562000a4757600080fd5b505af115801562000a5c573d6000803e3d6000fd5b50505050804762000a6e919062000fe8565b925050505b9392505050565b60006001600160a01b038216158062000a9b5750306001600160a01b038316145b8062000ad657506000826001600160a01b03163b11801562000ad657506001600160a01b0382166000908152600d602052604090205460ff16155b8062000afa57506001600160a01b03821660009081526012602052604090205460ff165b80620005025750506001600160a01b031661dead1490565b60408051606081018252825481526001830154602082015260028301549181019190915260009062000b449062000b69565b600183015550600754600290910155565b62000b64838383600162000bd3565b505050565b600080826040015160075462000b80919062000fe8565b90506000670de0b6b3a764000060805162000b9c919062000f85565b845162000bab90849062000f85565b62000bb7919062000fc5565b905080846020015162000bcb919062000ffe565b949350505050565b6001600160a01b03841662000bff5760405163e602df0560e01b81526000600482015260240162000099565b6001600160a01b03831662000c2b57604051634a1406b160e11b81526000600482015260240162000099565b6001600160a01b0380851660009081526002602090815260408083209387168352929052208290558015620007e757826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405162000ca091815260200190565b60405180910390a350505050565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168062000cd957607f821691505b60208210810362000cfa57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000b64576000816000526020600020601f850160051c8101602086101562000d2b5750805b601f850160051c820191505b8181101562000d4c5782815560010162000d37565b505050505050565b81516001600160401b0381111562000d705762000d7062000cae565b62000d888162000d81845462000cc4565b8462000d00565b602080601f83116001811462000dc0576000841562000da75750858301515b600019600386901b1c1916600185901b17855562000d4c565b600085815260208120601f198616915b8281101562000df15788860151825594840194600190910190840162000dd0565b508582101562000e105787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020828403121562000e3357600080fd5b815160ff8116811462000a7357600080fd5b634e487b7160e01b600052601160045260246000fd5b60ff828116828216039081111562000502576200050262000e45565b600181815b8085111562000eb857816000190482111562000e9c5762000e9c62000e45565b8085161562000eaa57918102915b93841c939080029062000e7c565b509250929050565b60008262000ed15750600162000502565b8162000ee05750600062000502565b816001811462000ef9576002811462000f045762000f24565b600191505062000502565b60ff84111562000f185762000f1862000e45565b50506001821b62000502565b5060208310610133831016604e8410600b841016171562000f49575081810a62000502565b62000f55838362000e77565b806000190482111562000f6c5762000f6c62000e45565b029392505050565b600062000a7360ff84168362000ec0565b808202811582820484141762000502576200050262000e45565b62ffffff81811683821601908082111562000fbe5762000fbe62000e45565b5092915050565b60008262000fe357634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111562000502576200050262000e45565b8082018082111562000502576200050262000e45565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156200103d57600080fd5b81516001600160a01b038116811462000a7357600080fd5b600060a08201878352602087602085015260a0604085015281875180845260c08601915060208901935060005b81811015620010a95784516001600160a01b03168352938301939183019160010162001082565b50506001600160a01b03969096166060850152505050608001529392505050565b608051612c93620010ed600039600081816113910152611b450152612c936000f3fe6080604052600436106103905760003560e01c806373dd250c116101dc578063c38ed94111610102578063e7e82b69116100a0578063f8b45b051161006f578063f8b45b0514610a3e578063fabb0b4f14610a54578063fe33b30214610a6e578063fe575a8714610a9e57600080fd5b8063e7e82b691461099e578063f2fde38b146109ce578063f7c618c1146109ee578063f887ea4014610a1657600080fd5b8063d7406965116100dc578063d740696514610903578063dbfa0bb514610923578063dd62ed3e14610943578063e7e3a24d1461098957600080fd5b8063c38ed941146108b8578063c9329ed2146108d8578063cebd7ae8146108ee57600080fd5b80639266cc2a1161017a578063afb62e5611610149578063afb62e561461083b578063b3ab15fb14610850578063b78b52df14610870578063c31c9c071461089057600080fd5b80639266cc2a146107dc57806395d89b41146107f1578063a9059cbb14610806578063aa5c3ab41461082657600080fd5b80638129fc1c116101b65780638129fc1c146107815780638da5cb5b14610789578063909921c7146107a757806391c05b0b146107bc57600080fd5b806373dd250c1461072c578063751039fc1461074c57806379cc67901461076157600080fd5b8063313ce567116102c1578063554c798a1161025f5780636b67c4df1161022e5780636b67c4df146106be5780636f83f6a2146106e157806370a08231146106f7578063715018a61461071757600080fd5b8063554c798a1461063a578063570ca7351461065057806359303a111461068857806366edecce146106a857600080fd5b806342966c681161029b57806342966c68146105c057806347062402146105e057806348cd4cb114610604578063537df3b61461061a57600080fd5b8063313ce5671461056857806331d7a2621461058a5780633a98ef39146105aa57600080fd5b80631e83409a1161032e57806323b872dd1161030857806323b872dd146104ef5780632568d7c41461050f5780632b14ca561461052f57806330188ee81461055257600080fd5b80631e83409a146104995780631eb7cfcb146104b95780632251c730146104d957600080fd5b806309094d661161036a57806309094d661461041e578063095ea7b314610434578063180b0d7e1461046457806318160ddd1461047a57600080fd5b806301681a621461039c57806306fdde03146103be578063089fe6aa146103e957600080fd5b3661039757005b600080fd5b3480156103a857600080fd5b506103bc6103b7366004612894565b610ace565b005b3480156103ca57600080fd5b506103d3610c2f565b6040516103e091906128d5565b60405180910390f35b3480156103f557600080fd5b5060155461040a90610100900462ffffff1681565b60405162ffffff90911681526020016103e0565b34801561042a57600080fd5b5061040a611f4081565b34801561044057600080fd5b5061045461044f366004612908565b610cc1565b60405190151581526020016103e0565b34801561047057600080fd5b5061040a61271081565b34801561048657600080fd5b506003545b6040519081526020016103e0565b3480156104a557600080fd5b506103bc6104b4366004612894565b610cdb565b3480156104c557600080fd5b506103bc6104d4366004612894565b610da1565b3480156104e557600080fd5b5061048b60105481565b3480156104fb57600080fd5b5061045461050a366004612934565b610eb6565b34801561051b57600080fd5b506103bc61052a366004612894565b610edc565b34801561053b57600080fd5b5060155461040a90600160381b900462ffffff1681565b34801561055e57600080fd5b5061048b600b5481565b34801561057457600080fd5b5060125b60405160ff90911681526020016103e0565b34801561059657600080fd5b5061048b6105a5366004612894565b610fa8565b3480156105b657600080fd5b5061048b60085481565b3480156105cc57600080fd5b506103bc6105db366004612975565b610fec565b3480156105ec57600080fd5b5060155461040a90640100000000900462ffffff1681565b34801561061057600080fd5b5061048b60145481565b34801561062657600080fd5b506103bc610635366004612894565b610ff6565b34801561064657600080fd5b5061048b600e5481565b34801561065c57600080fd5b50601154610670906001600160a01b031681565b6040516001600160a01b0390911681526020016103e0565b34801561069457600080fd5b506103bc6106a3366004612975565b611007565b3480156106b457600080fd5b5061040a610bb881565b3480156106ca57600080fd5b5060155461040a90600160501b900462ffffff1681565b3480156106ed57600080fd5b5061048b600a5481565b34801561070357600080fd5b5061048b610712366004612894565b611036565b34801561072357600080fd5b506103bc611051565b34801561073857600080fd5b506103bc6107473660046129a6565b611065565b34801561075857600080fd5b506103bc6110af565b34801561076d57600080fd5b506103bc61077c366004612908565b6110bf565b6103bc6110d8565b34801561079557600080fd5b506000546001600160a01b0316610670565b3480156107b357600080fd5b5061048b6112bb565b3480156107c857600080fd5b506103bc6107d7366004612975565b61133b565b3480156107e857600080fd5b506103bc61143c565b3480156107fd57600080fd5b506103d3611493565b34801561081257600080fd5b50610454610821366004612908565b6114a2565b34801561083257600080fd5b5061048b6114b0565b34801561084757600080fd5b5061048b61154b565b34801561085c57600080fd5b506103bc61086b366004612894565b61156c565b34801561087c57600080fd5b506103bc61088b366004612908565b6115fc565b34801561089c57600080fd5b5061067073e592427a0aece92de3edee1f18e0157c0586156481565b3480156108c457600080fd5b506103bc6108d33660046129c1565b6116b9565b3480156108e457600080fd5b5061048b600f5481565b3480156108fa57600080fd5b506103bc6117e3565b34801561090f57600080fd5b506103bc61091e366004612975565b611837565b34801561092f57600080fd5b506103bc61093e366004612975565b611875565b34801561094f57600080fd5b5061048b61095e366004612a04565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b34801561099557600080fd5b506103bc611911565b3480156109aa57600080fd5b506104546109b9366004612894565b600d6020526000908152604090205460ff1681565b3480156109da57600080fd5b506103bc6109e9366004612894565b611942565b3480156109fa57600080fd5b506106707377e06c9eccf2e797fd462a92b6d7642ef85b0a4481565b348015610a2257600080fd5b50610670737a250d5630b4cf539739df2c5dacb4c659f2488d81565b348015610a4a57600080fd5b5061048b60135481565b348015610a6057600080fd5b506015546105789060ff1681565b348015610a7a57600080fd5b50610454610a89366004612894565b600c6020526000908152604090205460ff1681565b348015610aaa57600080fd5b50610454610ab9366004612894565b60126020526000908152604090205460ff1681565b306001600160a01b03821603610b145760405162461bcd60e51b815260206004820152600660248201526502173776565760d41b60448201526064015b60405180910390fd5b7377e06c9eccf2e797fd462a92b6d7642ef85b0a43196001600160a01b03821601610b6a5760405162461bcd60e51b815260206004820152600660248201526502173776565760d41b6044820152606401610b0b565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610bb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd59190612a3d565b9050610beb6001600160a01b038316338361197d565b6040518181526001600160a01b0383169033907fed679328aebf74ede77ae09efcf36e90244f83643dadac1c2d9f0b21a46f6ab79060200160405180910390a35050565b606060048054610c3e90612a56565b80601f0160208091040260200160405190810160405280929190818152602001828054610c6a90612a56565b8015610cb75780601f10610c8c57610100808354040283529160200191610cb7565b820191906000526020600020905b815481529060010190602001808311610c9a57829003601f168201915b5050505050905090565b600033610ccf8185856119cf565b60019150505b92915050565b610ce36119dc565b336000908152600960205260409020610cfb81611a06565b60018101546000819003610d10575050610d94565b6000826001018190555080600a6000828254610d2c9190612aa6565b90915550610d5190507377e06c9eccf2e797fd462a92b6d7642ef85b0a44848361197d565b6040518181526001600160a01b0384169033907f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870689060200160405180910390a350505b610d9e6001600655565b50565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190612ab9565b60405163e6a4390560e01b81526001600160a01b03848116600483015230602483015291925060009183169063e6a4390590604401602060405180830381865afa158015610e6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8f9190612ab9565b6001600160a01b03166000908152600c60205260409020805460ff19166001179055505050565b600033610ec4858285611a47565b610ecf858585611abf565b60019150505b9392505050565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f549190612ab9565b6040516364e329cb60e11b81526001600160a01b03848116600483015230602483015291925060009183169063c9c65396906044016020604051808303816000875af1158015610e6b573d6000803e3d6000fd5b6001600160a01b03811660009081526009602090815260408083208151606081018352815481526001820154938101939093526002015490820152610cd590611b1e565b610d9e3382611b9a565b610ffe611bd0565b610d9e81611bfd565b6011546001600160a01b031633146110315760405162461bcd60e51b8152600401610b0b90612ad6565b600e55565b6001600160a01b031660009081526001602052604090205490565b611059611bd0565b6110636000611c5e565b565b6011546001600160a01b0316331461108f5760405162461bcd60e51b8152600401610b0b90612ad6565b6015805462ffffff9092166101000263ffffff0019909216919091179055565b6110b7611bd0565b600019601355565b6110ca823383611a47565b6110d48282611b9a565b5050565b6110e0611bd0565b6000341161111d5760405162461bcd60e51b815260206004820152600a602482015269216c697175696469747960b01b6044820152606401610b0b565b6014541561115c5760405162461bcd60e51b815260206004820152600c60248201526b085a5b9a5d1a585b1a5e995960a21b6044820152606401610b0b565b43601455606461116b60035490565b6111759190612af9565b601355600061118330611036565b90506111fe737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111da573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052a9190612ab9565b61121d30737a250d5630b4cf539739df2c5dacb4c659f2488d836119cf565b60405163f305d71960e01b81523060048201526024810182905260006044820181905260648201523360848201524260a4820152737a250d5630b4cf539739df2c5dacb4c659f2488d9063f305d71990349060c40160606040518083038185885af1158015611290573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906112b59190612b1b565b50505050565b60006010546000036112cd5750600090565b600e546000036112dd5750600090565b60006112e76114b0565b9050806000036112f957600091505090565b6000601054436113099190612b49565b600e546113169190612b5c565b600f546113239190612aa6565b90508181106113325781611334565b805b9250505090565b6008546000036113485750565b60006113526112bb565b905047801561137357611366308285611cae565b6113709083612aa6565b91505b8160000361138057505050565b600854670de0b6b3a76400006113b67f000000000000000000000000000000000000000000000000000000000000000085612b5c565b6113c09190612b5c565b6113ca9190612af9565b600760008282546113db9190612aa6565b9250508190555081600b60008282546113f49190612aa6565b90915550506000600f554360105560405182815233907fc1d32ad5cca423e7dda2123dbf8c482f8e77d00b631c06e903a47f2cec1334df9060200160405180910390a2505050565b61144533611e80565b336000818152600d6020908152604091829020805460ff1916905590519182527f9d987f025241c15852f6fdf907bfad8c5c84f316a13b8855ba5185bf79a3f7bb91015b60405180910390a1565b606060058054610c3e90612a56565b600033610ccf818585611abf565b600080600a54600b546114c39190612b49565b6040516370a0823160e01b815230600482015290915081907377e06c9eccf2e797fd462a92b6d7642ef85b0a44906370a0823190602401602060405180830381865afa158015611517573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061153b9190612a3d565b6115459190612b49565b91505090565b60006115556112bb565b61155d6114b0565b6115679190612b49565b905090565b6011546001600160a01b031633146115965760405162461bcd60e51b8152600401610b0b90612ad6565b6001600160a01b0381166000036115da5760405162461bcd60e51b8152602060048201526008602482015267216164647265737360c01b6044820152606401610b0b565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b611604611bd0565b601454156116435760405162461bcd60e51b815260206004820152600c60248201526b085a5b9a5d1a585b1a5e995960a21b6044820152606401610b0b565b60405163a9059cbb60e01b81526001600160a01b038316600482015260248101829052309063a9059cbb906044016020604051808303816000875af1158015611690573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b49190612b73565b505050565b6116c1611bd0565b610bb862ffffff841611156117025760405162461bcd60e51b81526020600482015260076024820152662162757946656560c81b6044820152606401610b0b565b610bb862ffffff831611156117445760405162461bcd60e51b81526020600482015260086024820152672173656c6c46656560c01b6044820152606401610b0b565b611f4062ffffff8216111561178b5760405162461bcd60e51b815260206004820152600d60248201526c216d61726b6574696e6746656560981b6044820152606401610b0b565b6015805469ffffffffffff00000000191664010000000062ffffff9586160269ffffff00000000000000191617600160381b938516939093029290921762ffffff60501b1916600160501b9190931602919091179055565b6117ec33611ed8565b336000818152600d6020908152604091829020805460ff1916600117905590519182527f6d2f2ea0335c8c0e296412085b47e0ed0c1b67b6bde3f5739e7739ca804a75b19101611489565b6011546001600160a01b031633146118615760405162461bcd60e51b8152600401610b0b90612ad6565b6118696112bb565b600f55600e5543601055565b600061188030611036565b90508060000361188e575050565b600061189b308385611f33565b601554909150600090612710906118be90600160501b900462ffffff1684612b5c565b6118c89190612af9565b905080156112b5576011546040516001600160a01b039091169082156108fc029083906000818181858888f1935050505015801561190a573d6000803e3d6000fd5b5050505050565b6011546001600160a01b0316331461193b5760405162461bcd60e51b8152600401610b0b90612ad6565b6000600f55565b61194a611bd0565b6001600160a01b03811661197457604051631e4fbdf760e01b815260006004820152602401610b0b565b610d9e81611c5e565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526116b49084906120e3565b6116b48383836001612146565b6002600654036119ff57604051633ee5aeb560e01b815260040160405180910390fd5b6002600655565b604080516060810182528254815260018301546020820152600283015491810191909152600090611a3690611b1e565b600183015550600754600290910155565b6001600160a01b0383811660009081526002602090815260408083209386168352929052205460001981146112b55781811015611ab057604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610b0b565b6112b584848484036000612146565b6001600160a01b038316611ae957604051634b637e8f60e11b815260006004820152602401610b0b565b6001600160a01b038216611b135760405163ec442f0560e01b815260006004820152602401610b0b565b6116b483838361221b565b6000808260400151600754611b339190612b49565b90506000611b69670de0b6b3a76400007f0000000000000000000000000000000000000000000000000000000000000000612b5c565b8451611b76908490612b5c565b611b809190612af9565b9050808460200151611b929190612aa6565b949350505050565b6001600160a01b038216611bc457604051634b637e8f60e11b815260006004820152602401610b0b565b6110d48260008361221b565b6000546001600160a01b031633146110635760405163118cdaa760e01b8152336004820152602401610b0b565b611c0681611ed8565b6001600160a01b038116600081815260126020908152604091829020805460ff1916905590519182527f3afada3900b4909463d8a846fbdc12d6b5c4e8030bd6bc1215822ecee62357ba91015b60405180910390a150565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600082600003611cc057506000610ed5565b6000604051806101000160405280737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d449190612ab9565b6001600160a01b0390811682527377e06c9eccf2e797fd462a92b6d7642ef85b0a44602080840191909152601554610100900462ffffff9081166040808601919091528a84166060808701919091524260808088019190915260a08088018d905260c08089018d9052600060e0998a0152845163414bf38960e01b81528a5189166004820152968a015188166024880152938901519094166044860152908701518516606485015286015160848401529085015160a483015284015160c4820152918301511660e482015290915073e592427a0aece92de3edee1f18e0157c058615649063414bf3899086906101040160206040518083038185885af1158015611e52573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611e779190612a3d565b95945050505050565b611e898161240d565b15611e915750565b611e9a81611036565b60086000828254611eab9190612b49565b90915550506001600160a01b0381166000908152600960205260409020611ed181611a06565b6000905550565b611ee18161240d565b611ee85750565b6000611ef382611036565b90508060086000828254611f079190612aa6565b90915550506001600160a01b039091166000908152600960205260409020908155600754600290910155565b600082600003611f4557506000610ed5565b611f6430737a250d5630b4cf539739df2c5dacb4c659f2488d856119cf565b6040805160028082526060820183526000926020830190803683370190505090503081600081518110611f9957611f99612b95565b60200260200101906001600160a01b031690816001600160a01b031681525050737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801561200b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202f9190612ab9565b8160018151811061204257612042612b95565b6001600160a01b039092166020928302919091019091015260405163791ac94760e01b81524790737a250d5630b4cf539739df2c5dacb4c659f2488d9063791ac9479061209b908890889087908c904290600401612bab565b600060405180830381600087803b1580156120b557600080fd5b505af11580156120c9573d6000803e3d6000fd5b5050505080476120d99190612b49565b9695505050505050565b60006120f86001600160a01b038416836124a0565b9050805160001415801561211d57508080602001905181019061211b9190612b73565b155b156116b457604051635274afe760e01b81526001600160a01b0384166004820152602401610b0b565b6001600160a01b0384166121705760405163e602df0560e01b815260006004820152602401610b0b565b6001600160a01b03831661219a57604051634a1406b160e11b815260006004820152602401610b0b565b6001600160a01b03808516600090815260026020908152604080832093871683529290522082905580156112b557826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161220d91815260200190565b60405180910390a350505050565b6001600160a01b03831660009081526012602052604090205460ff16156122725760405162461bcd60e51b815260206004820152600b60248201526a189b1858dadb1a5cdd195960aa1b6044820152606401610b0b565b6001600160a01b0383166000908152600c602052604081205460ff1680156122a0575061229e836124ae565b155b905060006122ad856124ae565b1580156122d257506001600160a01b0384166000908152600c602052604090205460ff165b90506000816122e25760006122f2565b601554600160381b900462ffffff165b836122fe57600061230f565b601554640100000000900462ffffff165b6123199190612c1e565b62ffffff169050600061271061232f8387612b5c565b6123399190612af9565b905060006123478287612b49565b905084801561235957506123596124e5565b156123675761236787612505565b61237087612562565b6123c55760135461238088611036565b61238a9083612aa6565b11156123c55760405162461bcd60e51b815260206004820152600a602482015269085b585e15d85b1b195d60b21b6044820152606401610b0b565b81156123d6576123d68830846125df565b83156123e6576123e66000611875565b6123f18888836125df565b6123fa88612709565b61240387612709565b5050505050505050565b60006001600160a01b038216158061242d5750306001600160a01b038316145b8061246657506000826001600160a01b03163b11801561246657506001600160a01b0382166000908152600d602052604090205460ff16155b8061248957506001600160a01b03821660009081526012602052604090205460ff165b80610cd55750506001600160a01b031661dead1490565b6060610ed58383600061276c565b6000306001600160a01b0383161480610cd55750506001600160a01b0316737a250d5630b4cf539739df2c5dacb4c659f2488d1490565b6015546014546000916124fd9160ff90911690612aa6565b431115905090565b61250e81611e80565b6001600160a01b038116600081815260126020908152604091829020805460ff1916600117905590519182527f6b713f4f12b0a0860e4b6b54d27ef8de95da632b1250f5c12f8254fdedbc2ebd9101611c53565b6000306001600160a01b03831614806125975750737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b038316145b806125ba57506001600160a01b0382166000908152600c602052604090205460ff165b80610cd55750506001600160a01b031660009081526012602052604090205460ff1690565b6001600160a01b03831661260a5780600360008282546125ff9190612aa6565b9091555061267c9050565b6001600160a01b0383166000908152600160205260409020548181101561265d5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610b0b565b6001600160a01b03841660009081526001602052604090209082900390555b6001600160a01b038216612698576003805482900390556126b7565b6001600160a01b03821660009081526001602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516126fc91815260200190565b60405180910390a3505050565b6127128161240d565b1561271a5750565b600061272582611036565b6001600160a01b038316600090815260096020526040902080546008549293509091839161275291612b49565b61275c9190612aa6565b60085561276881611a06565b5550565b6060814710156127915760405163cd78605960e01b8152306004820152602401610b0b565b600080856001600160a01b031684866040516127ad9190612c41565b60006040518083038185875af1925050503d80600081146127ea576040519150601f19603f3d011682016040523d82523d6000602084013e6127ef565b606091505b50915091506120d986838360608261280f5761280a82612856565b610ed5565b815115801561282657506001600160a01b0384163b155b1561284f57604051639996b31560e01b81526001600160a01b0385166004820152602401610b0b565b5080610ed5565b8051156128665780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b0381168114610d9e57600080fd5b6000602082840312156128a657600080fd5b8135610ed58161287f565b60005b838110156128cc5781810151838201526020016128b4565b50506000910152565b60208152600082518060208401526128f48160408501602087016128b1565b601f01601f19169190910160400192915050565b6000806040838503121561291b57600080fd5b82356129268161287f565b946020939093013593505050565b60008060006060848603121561294957600080fd5b83356129548161287f565b925060208401356129648161287f565b929592945050506040919091013590565b60006020828403121561298757600080fd5b5035919050565b803562ffffff811681146129a157600080fd5b919050565b6000602082840312156129b857600080fd5b610ed58261298e565b6000806000606084860312156129d657600080fd5b6129df8461298e565b92506129ed6020850161298e565b91506129fb6040850161298e565b90509250925092565b60008060408385031215612a1757600080fd5b8235612a228161287f565b91506020830135612a328161287f565b809150509250929050565b600060208284031215612a4f57600080fd5b5051919050565b600181811c90821680612a6a57607f821691505b602082108103612a8a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610cd557610cd5612a90565b600060208284031215612acb57600080fd5b8151610ed58161287f565b60208082526009908201526810b7b832b930ba37b960b91b604082015260600190565b600082612b1657634e487b7160e01b600052601260045260246000fd5b500490565b600080600060608486031215612b3057600080fd5b8351925060208401519150604084015190509250925092565b81810381811115610cd557610cd5612a90565b8082028115828204841417610cd557610cd5612a90565b600060208284031215612b8557600080fd5b81518015158114610ed557600080fd5b634e487b7160e01b600052603260045260246000fd5b600060a08201878352602087602085015260a0604085015281875180845260c08601915060208901935060005b81811015612bfd5784516001600160a01b031683529383019391830191600101612bd8565b50506001600160a01b03969096166060850152505050608001529392505050565b62ffffff818116838216019080821115612c3a57612c3a612a90565b5092915050565b60008251612c538184602087016128b1565b919091019291505056fea26469706673582212207cf7062cb623c26255eb2d98ae2e3abec8ceb2d3f53b33f6ce8296bbb7dc965564736f6c634300081700330000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d

Deployed Bytecode

0x6080604052600436106103905760003560e01c806373dd250c116101dc578063c38ed94111610102578063e7e82b69116100a0578063f8b45b051161006f578063f8b45b0514610a3e578063fabb0b4f14610a54578063fe33b30214610a6e578063fe575a8714610a9e57600080fd5b8063e7e82b691461099e578063f2fde38b146109ce578063f7c618c1146109ee578063f887ea4014610a1657600080fd5b8063d7406965116100dc578063d740696514610903578063dbfa0bb514610923578063dd62ed3e14610943578063e7e3a24d1461098957600080fd5b8063c38ed941146108b8578063c9329ed2146108d8578063cebd7ae8146108ee57600080fd5b80639266cc2a1161017a578063afb62e5611610149578063afb62e561461083b578063b3ab15fb14610850578063b78b52df14610870578063c31c9c071461089057600080fd5b80639266cc2a146107dc57806395d89b41146107f1578063a9059cbb14610806578063aa5c3ab41461082657600080fd5b80638129fc1c116101b65780638129fc1c146107815780638da5cb5b14610789578063909921c7146107a757806391c05b0b146107bc57600080fd5b806373dd250c1461072c578063751039fc1461074c57806379cc67901461076157600080fd5b8063313ce567116102c1578063554c798a1161025f5780636b67c4df1161022e5780636b67c4df146106be5780636f83f6a2146106e157806370a08231146106f7578063715018a61461071757600080fd5b8063554c798a1461063a578063570ca7351461065057806359303a111461068857806366edecce146106a857600080fd5b806342966c681161029b57806342966c68146105c057806347062402146105e057806348cd4cb114610604578063537df3b61461061a57600080fd5b8063313ce5671461056857806331d7a2621461058a5780633a98ef39146105aa57600080fd5b80631e83409a1161032e57806323b872dd1161030857806323b872dd146104ef5780632568d7c41461050f5780632b14ca561461052f57806330188ee81461055257600080fd5b80631e83409a146104995780631eb7cfcb146104b95780632251c730146104d957600080fd5b806309094d661161036a57806309094d661461041e578063095ea7b314610434578063180b0d7e1461046457806318160ddd1461047a57600080fd5b806301681a621461039c57806306fdde03146103be578063089fe6aa146103e957600080fd5b3661039757005b600080fd5b3480156103a857600080fd5b506103bc6103b7366004612894565b610ace565b005b3480156103ca57600080fd5b506103d3610c2f565b6040516103e091906128d5565b60405180910390f35b3480156103f557600080fd5b5060155461040a90610100900462ffffff1681565b60405162ffffff90911681526020016103e0565b34801561042a57600080fd5b5061040a611f4081565b34801561044057600080fd5b5061045461044f366004612908565b610cc1565b60405190151581526020016103e0565b34801561047057600080fd5b5061040a61271081565b34801561048657600080fd5b506003545b6040519081526020016103e0565b3480156104a557600080fd5b506103bc6104b4366004612894565b610cdb565b3480156104c557600080fd5b506103bc6104d4366004612894565b610da1565b3480156104e557600080fd5b5061048b60105481565b3480156104fb57600080fd5b5061045461050a366004612934565b610eb6565b34801561051b57600080fd5b506103bc61052a366004612894565b610edc565b34801561053b57600080fd5b5060155461040a90600160381b900462ffffff1681565b34801561055e57600080fd5b5061048b600b5481565b34801561057457600080fd5b5060125b60405160ff90911681526020016103e0565b34801561059657600080fd5b5061048b6105a5366004612894565b610fa8565b3480156105b657600080fd5b5061048b60085481565b3480156105cc57600080fd5b506103bc6105db366004612975565b610fec565b3480156105ec57600080fd5b5060155461040a90640100000000900462ffffff1681565b34801561061057600080fd5b5061048b60145481565b34801561062657600080fd5b506103bc610635366004612894565b610ff6565b34801561064657600080fd5b5061048b600e5481565b34801561065c57600080fd5b50601154610670906001600160a01b031681565b6040516001600160a01b0390911681526020016103e0565b34801561069457600080fd5b506103bc6106a3366004612975565b611007565b3480156106b457600080fd5b5061040a610bb881565b3480156106ca57600080fd5b5060155461040a90600160501b900462ffffff1681565b3480156106ed57600080fd5b5061048b600a5481565b34801561070357600080fd5b5061048b610712366004612894565b611036565b34801561072357600080fd5b506103bc611051565b34801561073857600080fd5b506103bc6107473660046129a6565b611065565b34801561075857600080fd5b506103bc6110af565b34801561076d57600080fd5b506103bc61077c366004612908565b6110bf565b6103bc6110d8565b34801561079557600080fd5b506000546001600160a01b0316610670565b3480156107b357600080fd5b5061048b6112bb565b3480156107c857600080fd5b506103bc6107d7366004612975565b61133b565b3480156107e857600080fd5b506103bc61143c565b3480156107fd57600080fd5b506103d3611493565b34801561081257600080fd5b50610454610821366004612908565b6114a2565b34801561083257600080fd5b5061048b6114b0565b34801561084757600080fd5b5061048b61154b565b34801561085c57600080fd5b506103bc61086b366004612894565b61156c565b34801561087c57600080fd5b506103bc61088b366004612908565b6115fc565b34801561089c57600080fd5b5061067073e592427a0aece92de3edee1f18e0157c0586156481565b3480156108c457600080fd5b506103bc6108d33660046129c1565b6116b9565b3480156108e457600080fd5b5061048b600f5481565b3480156108fa57600080fd5b506103bc6117e3565b34801561090f57600080fd5b506103bc61091e366004612975565b611837565b34801561092f57600080fd5b506103bc61093e366004612975565b611875565b34801561094f57600080fd5b5061048b61095e366004612a04565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b34801561099557600080fd5b506103bc611911565b3480156109aa57600080fd5b506104546109b9366004612894565b600d6020526000908152604090205460ff1681565b3480156109da57600080fd5b506103bc6109e9366004612894565b611942565b3480156109fa57600080fd5b506106707377e06c9eccf2e797fd462a92b6d7642ef85b0a4481565b348015610a2257600080fd5b50610670737a250d5630b4cf539739df2c5dacb4c659f2488d81565b348015610a4a57600080fd5b5061048b60135481565b348015610a6057600080fd5b506015546105789060ff1681565b348015610a7a57600080fd5b50610454610a89366004612894565b600c6020526000908152604090205460ff1681565b348015610aaa57600080fd5b50610454610ab9366004612894565b60126020526000908152604090205460ff1681565b306001600160a01b03821603610b145760405162461bcd60e51b815260206004820152600660248201526502173776565760d41b60448201526064015b60405180910390fd5b7377e06c9eccf2e797fd462a92b6d7642ef85b0a43196001600160a01b03821601610b6a5760405162461bcd60e51b815260206004820152600660248201526502173776565760d41b6044820152606401610b0b565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610bb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd59190612a3d565b9050610beb6001600160a01b038316338361197d565b6040518181526001600160a01b0383169033907fed679328aebf74ede77ae09efcf36e90244f83643dadac1c2d9f0b21a46f6ab79060200160405180910390a35050565b606060048054610c3e90612a56565b80601f0160208091040260200160405190810160405280929190818152602001828054610c6a90612a56565b8015610cb75780601f10610c8c57610100808354040283529160200191610cb7565b820191906000526020600020905b815481529060010190602001808311610c9a57829003601f168201915b5050505050905090565b600033610ccf8185856119cf565b60019150505b92915050565b610ce36119dc565b336000908152600960205260409020610cfb81611a06565b60018101546000819003610d10575050610d94565b6000826001018190555080600a6000828254610d2c9190612aa6565b90915550610d5190507377e06c9eccf2e797fd462a92b6d7642ef85b0a44848361197d565b6040518181526001600160a01b0384169033907f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870689060200160405180910390a350505b610d9e6001600655565b50565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610df5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e199190612ab9565b60405163e6a4390560e01b81526001600160a01b03848116600483015230602483015291925060009183169063e6a4390590604401602060405180830381865afa158015610e6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8f9190612ab9565b6001600160a01b03166000908152600c60205260409020805460ff19166001179055505050565b600033610ec4858285611a47565b610ecf858585611abf565b60019150505b9392505050565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f549190612ab9565b6040516364e329cb60e11b81526001600160a01b03848116600483015230602483015291925060009183169063c9c65396906044016020604051808303816000875af1158015610e6b573d6000803e3d6000fd5b6001600160a01b03811660009081526009602090815260408083208151606081018352815481526001820154938101939093526002015490820152610cd590611b1e565b610d9e3382611b9a565b610ffe611bd0565b610d9e81611bfd565b6011546001600160a01b031633146110315760405162461bcd60e51b8152600401610b0b90612ad6565b600e55565b6001600160a01b031660009081526001602052604090205490565b611059611bd0565b6110636000611c5e565b565b6011546001600160a01b0316331461108f5760405162461bcd60e51b8152600401610b0b90612ad6565b6015805462ffffff9092166101000263ffffff0019909216919091179055565b6110b7611bd0565b600019601355565b6110ca823383611a47565b6110d48282611b9a565b5050565b6110e0611bd0565b6000341161111d5760405162461bcd60e51b815260206004820152600a602482015269216c697175696469747960b01b6044820152606401610b0b565b6014541561115c5760405162461bcd60e51b815260206004820152600c60248201526b085a5b9a5d1a585b1a5e995960a21b6044820152606401610b0b565b43601455606461116b60035490565b6111759190612af9565b601355600061118330611036565b90506111fe737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111da573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052a9190612ab9565b61121d30737a250d5630b4cf539739df2c5dacb4c659f2488d836119cf565b60405163f305d71960e01b81523060048201526024810182905260006044820181905260648201523360848201524260a4820152737a250d5630b4cf539739df2c5dacb4c659f2488d9063f305d71990349060c40160606040518083038185885af1158015611290573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906112b59190612b1b565b50505050565b60006010546000036112cd5750600090565b600e546000036112dd5750600090565b60006112e76114b0565b9050806000036112f957600091505090565b6000601054436113099190612b49565b600e546113169190612b5c565b600f546113239190612aa6565b90508181106113325781611334565b805b9250505090565b6008546000036113485750565b60006113526112bb565b905047801561137357611366308285611cae565b6113709083612aa6565b91505b8160000361138057505050565b600854670de0b6b3a76400006113b67f000000000000000000000000000000000000000000000000000000003b9aca0085612b5c565b6113c09190612b5c565b6113ca9190612af9565b600760008282546113db9190612aa6565b9250508190555081600b60008282546113f49190612aa6565b90915550506000600f554360105560405182815233907fc1d32ad5cca423e7dda2123dbf8c482f8e77d00b631c06e903a47f2cec1334df9060200160405180910390a2505050565b61144533611e80565b336000818152600d6020908152604091829020805460ff1916905590519182527f9d987f025241c15852f6fdf907bfad8c5c84f316a13b8855ba5185bf79a3f7bb91015b60405180910390a1565b606060058054610c3e90612a56565b600033610ccf818585611abf565b600080600a54600b546114c39190612b49565b6040516370a0823160e01b815230600482015290915081907377e06c9eccf2e797fd462a92b6d7642ef85b0a44906370a0823190602401602060405180830381865afa158015611517573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061153b9190612a3d565b6115459190612b49565b91505090565b60006115556112bb565b61155d6114b0565b6115679190612b49565b905090565b6011546001600160a01b031633146115965760405162461bcd60e51b8152600401610b0b90612ad6565b6001600160a01b0381166000036115da5760405162461bcd60e51b8152602060048201526008602482015267216164647265737360c01b6044820152606401610b0b565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b611604611bd0565b601454156116435760405162461bcd60e51b815260206004820152600c60248201526b085a5b9a5d1a585b1a5e995960a21b6044820152606401610b0b565b60405163a9059cbb60e01b81526001600160a01b038316600482015260248101829052309063a9059cbb906044016020604051808303816000875af1158015611690573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b49190612b73565b505050565b6116c1611bd0565b610bb862ffffff841611156117025760405162461bcd60e51b81526020600482015260076024820152662162757946656560c81b6044820152606401610b0b565b610bb862ffffff831611156117445760405162461bcd60e51b81526020600482015260086024820152672173656c6c46656560c01b6044820152606401610b0b565b611f4062ffffff8216111561178b5760405162461bcd60e51b815260206004820152600d60248201526c216d61726b6574696e6746656560981b6044820152606401610b0b565b6015805469ffffffffffff00000000191664010000000062ffffff9586160269ffffff00000000000000191617600160381b938516939093029290921762ffffff60501b1916600160501b9190931602919091179055565b6117ec33611ed8565b336000818152600d6020908152604091829020805460ff1916600117905590519182527f6d2f2ea0335c8c0e296412085b47e0ed0c1b67b6bde3f5739e7739ca804a75b19101611489565b6011546001600160a01b031633146118615760405162461bcd60e51b8152600401610b0b90612ad6565b6118696112bb565b600f55600e5543601055565b600061188030611036565b90508060000361188e575050565b600061189b308385611f33565b601554909150600090612710906118be90600160501b900462ffffff1684612b5c565b6118c89190612af9565b905080156112b5576011546040516001600160a01b039091169082156108fc029083906000818181858888f1935050505015801561190a573d6000803e3d6000fd5b5050505050565b6011546001600160a01b0316331461193b5760405162461bcd60e51b8152600401610b0b90612ad6565b6000600f55565b61194a611bd0565b6001600160a01b03811661197457604051631e4fbdf760e01b815260006004820152602401610b0b565b610d9e81611c5e565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526116b49084906120e3565b6116b48383836001612146565b6002600654036119ff57604051633ee5aeb560e01b815260040160405180910390fd5b6002600655565b604080516060810182528254815260018301546020820152600283015491810191909152600090611a3690611b1e565b600183015550600754600290910155565b6001600160a01b0383811660009081526002602090815260408083209386168352929052205460001981146112b55781811015611ab057604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610b0b565b6112b584848484036000612146565b6001600160a01b038316611ae957604051634b637e8f60e11b815260006004820152602401610b0b565b6001600160a01b038216611b135760405163ec442f0560e01b815260006004820152602401610b0b565b6116b483838361221b565b6000808260400151600754611b339190612b49565b90506000611b69670de0b6b3a76400007f000000000000000000000000000000000000000000000000000000003b9aca00612b5c565b8451611b76908490612b5c565b611b809190612af9565b9050808460200151611b929190612aa6565b949350505050565b6001600160a01b038216611bc457604051634b637e8f60e11b815260006004820152602401610b0b565b6110d48260008361221b565b6000546001600160a01b031633146110635760405163118cdaa760e01b8152336004820152602401610b0b565b611c0681611ed8565b6001600160a01b038116600081815260126020908152604091829020805460ff1916905590519182527f3afada3900b4909463d8a846fbdc12d6b5c4e8030bd6bc1215822ecee62357ba91015b60405180910390a150565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600082600003611cc057506000610ed5565b6000604051806101000160405280737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d449190612ab9565b6001600160a01b0390811682527377e06c9eccf2e797fd462a92b6d7642ef85b0a44602080840191909152601554610100900462ffffff9081166040808601919091528a84166060808701919091524260808088019190915260a08088018d905260c08089018d9052600060e0998a0152845163414bf38960e01b81528a5189166004820152968a015188166024880152938901519094166044860152908701518516606485015286015160848401529085015160a483015284015160c4820152918301511660e482015290915073e592427a0aece92de3edee1f18e0157c058615649063414bf3899086906101040160206040518083038185885af1158015611e52573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611e779190612a3d565b95945050505050565b611e898161240d565b15611e915750565b611e9a81611036565b60086000828254611eab9190612b49565b90915550506001600160a01b0381166000908152600960205260409020611ed181611a06565b6000905550565b611ee18161240d565b611ee85750565b6000611ef382611036565b90508060086000828254611f079190612aa6565b90915550506001600160a01b039091166000908152600960205260409020908155600754600290910155565b600082600003611f4557506000610ed5565b611f6430737a250d5630b4cf539739df2c5dacb4c659f2488d856119cf565b6040805160028082526060820183526000926020830190803683370190505090503081600081518110611f9957611f99612b95565b60200260200101906001600160a01b031690816001600160a01b031681525050737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801561200b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202f9190612ab9565b8160018151811061204257612042612b95565b6001600160a01b039092166020928302919091019091015260405163791ac94760e01b81524790737a250d5630b4cf539739df2c5dacb4c659f2488d9063791ac9479061209b908890889087908c904290600401612bab565b600060405180830381600087803b1580156120b557600080fd5b505af11580156120c9573d6000803e3d6000fd5b5050505080476120d99190612b49565b9695505050505050565b60006120f86001600160a01b038416836124a0565b9050805160001415801561211d57508080602001905181019061211b9190612b73565b155b156116b457604051635274afe760e01b81526001600160a01b0384166004820152602401610b0b565b6001600160a01b0384166121705760405163e602df0560e01b815260006004820152602401610b0b565b6001600160a01b03831661219a57604051634a1406b160e11b815260006004820152602401610b0b565b6001600160a01b03808516600090815260026020908152604080832093871683529290522082905580156112b557826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161220d91815260200190565b60405180910390a350505050565b6001600160a01b03831660009081526012602052604090205460ff16156122725760405162461bcd60e51b815260206004820152600b60248201526a189b1858dadb1a5cdd195960aa1b6044820152606401610b0b565b6001600160a01b0383166000908152600c602052604081205460ff1680156122a0575061229e836124ae565b155b905060006122ad856124ae565b1580156122d257506001600160a01b0384166000908152600c602052604090205460ff165b90506000816122e25760006122f2565b601554600160381b900462ffffff165b836122fe57600061230f565b601554640100000000900462ffffff165b6123199190612c1e565b62ffffff169050600061271061232f8387612b5c565b6123399190612af9565b905060006123478287612b49565b905084801561235957506123596124e5565b156123675761236787612505565b61237087612562565b6123c55760135461238088611036565b61238a9083612aa6565b11156123c55760405162461bcd60e51b815260206004820152600a602482015269085b585e15d85b1b195d60b21b6044820152606401610b0b565b81156123d6576123d68830846125df565b83156123e6576123e66000611875565b6123f18888836125df565b6123fa88612709565b61240387612709565b5050505050505050565b60006001600160a01b038216158061242d5750306001600160a01b038316145b8061246657506000826001600160a01b03163b11801561246657506001600160a01b0382166000908152600d602052604090205460ff16155b8061248957506001600160a01b03821660009081526012602052604090205460ff165b80610cd55750506001600160a01b031661dead1490565b6060610ed58383600061276c565b6000306001600160a01b0383161480610cd55750506001600160a01b0316737a250d5630b4cf539739df2c5dacb4c659f2488d1490565b6015546014546000916124fd9160ff90911690612aa6565b431115905090565b61250e81611e80565b6001600160a01b038116600081815260126020908152604091829020805460ff1916600117905590519182527f6b713f4f12b0a0860e4b6b54d27ef8de95da632b1250f5c12f8254fdedbc2ebd9101611c53565b6000306001600160a01b03831614806125975750737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b038316145b806125ba57506001600160a01b0382166000908152600c602052604090205460ff165b80610cd55750506001600160a01b031660009081526012602052604090205460ff1690565b6001600160a01b03831661260a5780600360008282546125ff9190612aa6565b9091555061267c9050565b6001600160a01b0383166000908152600160205260409020548181101561265d5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610b0b565b6001600160a01b03841660009081526001602052604090209082900390555b6001600160a01b038216612698576003805482900390556126b7565b6001600160a01b03821660009081526001602052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516126fc91815260200190565b60405180910390a3505050565b6127128161240d565b1561271a5750565b600061272582611036565b6001600160a01b038316600090815260096020526040902080546008549293509091839161275291612b49565b61275c9190612aa6565b60085561276881611a06565b5550565b6060814710156127915760405163cd78605960e01b8152306004820152602401610b0b565b600080856001600160a01b031684866040516127ad9190612c41565b60006040518083038185875af1925050503d80600081146127ea576040519150601f19603f3d011682016040523d82523d6000602084013e6127ef565b606091505b50915091506120d986838360608261280f5761280a82612856565b610ed5565b815115801561282657506001600160a01b0384163b155b1561284f57604051639996b31560e01b81526001600160a01b0385166004820152602401610b0b565b5080610ed5565b8051156128665780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b0381168114610d9e57600080fd5b6000602082840312156128a657600080fd5b8135610ed58161287f565b60005b838110156128cc5781810151838201526020016128b4565b50506000910152565b60208152600082518060208401526128f48160408501602087016128b1565b601f01601f19169190910160400192915050565b6000806040838503121561291b57600080fd5b82356129268161287f565b946020939093013593505050565b60008060006060848603121561294957600080fd5b83356129548161287f565b925060208401356129648161287f565b929592945050506040919091013590565b60006020828403121561298757600080fd5b5035919050565b803562ffffff811681146129a157600080fd5b919050565b6000602082840312156129b857600080fd5b610ed58261298e565b6000806000606084860312156129d657600080fd5b6129df8461298e565b92506129ed6020850161298e565b91506129fb6040850161298e565b90509250925092565b60008060408385031215612a1757600080fd5b8235612a228161287f565b91506020830135612a328161287f565b809150509250929050565b600060208284031215612a4f57600080fd5b5051919050565b600181811c90821680612a6a57607f821691505b602082108103612a8a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610cd557610cd5612a90565b600060208284031215612acb57600080fd5b8151610ed58161287f565b60208082526009908201526810b7b832b930ba37b960b91b604082015260600190565b600082612b1657634e487b7160e01b600052601260045260246000fd5b500490565b600080600060608486031215612b3057600080fd5b8351925060208401519150604084015190509250925092565b81810381811115610cd557610cd5612a90565b8082028115828204841417610cd557610cd5612a90565b600060208284031215612b8557600080fd5b81518015158114610ed557600080fd5b634e487b7160e01b600052603260045260246000fd5b600060a08201878352602087602085015260a0604085015281875180845260c08601915060208901935060005b81811015612bfd5784516001600160a01b031683529383019391830191600101612bd8565b50506001600160a01b03969096166060850152505050608001529392505050565b62ffffff818116838216019080821115612c3a57612c3a612a90565b5092915050565b60008251612c538184602087016128b1565b919091019291505056fea26469706673582212207cf7062cb623c26255eb2d98ae2e3abec8ceb2d3f53b33f6ce8296bbb7dc965564736f6c63430008170033

Deployed Bytecode Sourcemap

82091:94:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68903:375;;;;;;;;;;-1:-1:-1;68903:375:0;;;;;:::i;:::-;;:::i;:::-;;15879:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61484:29;;;;;;;;;;-1:-1:-1;61484:29:0;;;;;;;;;;;;;;1262:8:1;1250:21;;;1232:40;;1220:2;1205:18;61484:29:0;1088:190:1;61767:45:0;;;;;;;;;;;;61808:4;61767:45;;18172:190;;;;;;;;;;-1:-1:-1;18172:190:0;;;;;:::i;:::-;;:::i;:::-;;;1776:14:1;;1769:22;1751:41;;1739:2;1724:18;18172:190:0;1611:187:1;61819:45:0;;;;;;;;;;;;61859:5;61819:45;;16981:99;;;;;;;;;;-1:-1:-1;17060:12:0;;16981:99;;;1949:25:1;;;1937:2;1922:18;16981:99:0;1803:177:1;65487:418:0;;;;;;;;;;-1:-1:-1;65487:418:0;;;;;:::i;:::-;;:::i;66323:227::-;;;;;;;;;;-1:-1:-1;66323:227:0;;;;;:::i;:::-;;:::i;60285:32::-;;;;;;;;;;;;;;;;18940:249;;;;;;;;;;-1:-1:-1;18940:249:0;;;;;:::i;:::-;;:::i;65993:230::-;;;;;;;;;;-1:-1:-1;65993:230:0;;;;;:::i;:::-;;:::i;61907:28::-;;;;;;;;;;-1:-1:-1;61907:28:0;;;;-1:-1:-1;;;61907:28:0;;;;;;59524:37;;;;;;;;;;;;;;;;16832:84;;;;;;;;;;-1:-1:-1;16906:2:0;16832:84;;;2894:4:1;2882:17;;;2864:36;;2852:2;2837:18;16832:84:0;2722:184:1;65072:131:0;;;;;;;;;;-1:-1:-1;65072:131:0;;;;;:::i;:::-;;:::i;58909:26::-;;;;;;;;;;;;;;;;41720:89;;;;;;;;;;-1:-1:-1;41720:89:0;;;;;:::i;:::-;;:::i;61873:27::-;;;;;;;;;;-1:-1:-1;61873:27:0;;;;;;;;;;;61224:29;;;;;;;;;;;;;;;;70381:107;;;;;;;;;;-1:-1:-1;70381:107:0;;;;;:::i;:::-;;:::i;60098:34::-;;;;;;;;;;;;;;;;60860:23;;;;;;;;;;-1:-1:-1;60860:23:0;;;;-1:-1:-1;;;;;60860:23:0;;;;;;-1:-1:-1;;;;;3260:32:1;;;3242:51;;3230:2;3215:18;60860:23:0;3096:203:1;72726:151:0;;;;;;;;;;-1:-1:-1;72726:151:0;;;;;:::i;:::-;;:::i;61720:40::-;;;;;;;;;;;;61756:4;61720:40;;61942:33;;;;;;;;;;-1:-1:-1;61942:33:0;;;;-1:-1:-1;;;61942:33:0;;;;;;59426;;;;;;;;;;;;;;;;17143:118;;;;;;;;;;-1:-1:-1;17143:118:0;;;;;:::i;:::-;;:::i;3151:103::-;;;;;;;;;;;;;:::i;72098:96::-;;;;;;;;;;-1:-1:-1;72098:96:0;;;;;:::i;:::-;;:::i;69793:91::-;;;;;;;;;;;;;:::i;42138:161::-;;;;;;;;;;-1:-1:-1;42138:161:0;;;;;:::i;:::-;;:::i;70766:849::-;;;:::i;2476:87::-;;;;;;;;;;-1:-1:-1;2522:7:0;2549:6;-1:-1:-1;;;;;2549:6:0;2476:87;;64563:411;;;;;;;;;;;;;:::i;67878:935::-;;;;;;;;;;-1:-1:-1;67878:935:0;;;;;:::i;:::-;;:::i;66903:158::-;;;;;;;;;;;;;:::i;16089:95::-;;;;;;;;;;;;;:::i;17466:182::-;;;;;;;;;;-1:-1:-1;17466:182:0;;;;;:::i;:::-;;:::i;64184:213::-;;;;;;;;;;;;;:::i;63902:118::-;;;;;;;;;;;;;:::i;71879:156::-;;;;;;;;;;-1:-1:-1;71879:156:0;;;;;:::i;:::-;;:::i;69560:162::-;;;;;;;;;;-1:-1:-1;69560:162:0;;;;;:::i;:::-;;:::i;57941:96::-;;;;;;;;;;;;57994:42;57941:96;;69932:370;;;;;;;;;;-1:-1:-1;69932:370:0;;;;;:::i;:::-;;:::i;60193:32::-;;;;;;;;;;;;;;;;66650:154;;;;;;;;;;;;;:::i;72344:235::-;;;;;;;;;;-1:-1:-1;72344:235:0;;;;;:::i;:::-;;:::i;67201:543::-;;;;;;;;;;-1:-1:-1;67201:543:0;;;;;:::i;:::-;;:::i;17711:142::-;;;;;;;;;;-1:-1:-1;17711:142:0;;;;;:::i;:::-;-1:-1:-1;;;;;17818:18:0;;;17791:7;17818:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;17711:142;72965:99;;;;;;;;;;;;;:::i;59803:39::-;;;;;;;;;;-1:-1:-1;59803:39:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;3409:220;;;;;;;;;;-1:-1:-1;3409:220:0;;;;;:::i;:::-;;:::i;58157:103::-;;;;;;;;;;;;58217:42;58157:103;;58044:106;;;;;;;;;;;;58107:42;58044:106;;61146:44;;;;;;;;;;;;;;;;61260:27;;;;;;;;;;-1:-1:-1;61260:27:0;;;;;;;;59703:37;;;;;;;;;;-1:-1:-1;59703:37:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;61092:45;;;;;;;;;;-1:-1:-1;61092:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;68903:375;68996:4;-1:-1:-1;;;;;68965:36:0;;;68957:55;;;;-1:-1:-1;;;68957:55:0;;5296:2:1;68957:55:0;;;5278:21:1;5335:1;5315:18;;;5308:29;-1:-1:-1;;;5353:18:1;;;5346:36;5399:18;;68957:55:0;;;;;;;;;-1:-1:-1;;;;;;;69031:43:0;;;69023:62;;;;-1:-1:-1;;;69023:62:0;;5296:2:1;69023:62:0;;;5278:21:1;5335:1;5315:18;;;5308:29;-1:-1:-1;;;5353:18:1;;;5346:36;5399:18;;69023:62:0;5094:329:1;69023:62:0;69115:35;;-1:-1:-1;;;69115:35:0;;69144:4;69115:35;;;3242:51:1;69098:14:0;;-1:-1:-1;;;;;69115:20:0;;;;;3215:18:1;;69115:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;69098:52;-1:-1:-1;69163:43:0;-1:-1:-1;;;;;69163:23:0;;69187:10;69098:52;69163:23;:43::i;:::-;69224:46;;1949:25:1;;;-1:-1:-1;;;;;69224:46:0;;;69230:10;;69224:46;;1937:2:1;1922:18;69224:46:0;;;;;;;68946:332;68903:375;:::o;15879:91::-;15924:13;15957:5;15950:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15879:91;:::o;18172:190::-;18245:4;831:10;18301:31;831:10;18317:7;18326:5;18301:8;:31::i;:::-;18350:4;18343:11;;;18172:190;;;;;:::o;65487:418::-;44656:21;:19;:21::i;:::-;65582:10:::1;65547:19;65569:24:::0;;;:12:::1;:24;::::0;;;;65606:12:::1;65569:24:::0;65606:5:::1;:12::i;:::-;65655;::::0;::::1;::::0;65631:21:::1;65684:18:::0;;;65680:31:::1;;65704:7;;;;65680:31;65738:1;65723:5;:12;;:16;;;;65774:13;65752:18;;:35;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;65800:43:0::1;::::0;-1:-1:-1;58217:42:0::1;65825:2:::0;65829:13;65800:24:::1;:43::i;:::-;65861:36;::::0;1949:25:1;;;-1:-1:-1;;;;;65861:36:0;::::1;::::0;65867:10:::1;::::0;65861:36:::1;::::0;1937:2:1;1922:18;65861:36:0::1;;;;;;;65536:369;;44688:1;44700:20:::0;43991:1;45242:7;:21;45059:212;44700:20;65487:418;:::o;66323:227::-;66383:25;58107:42;-1:-1:-1;;;;;66429:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66474:37;;-1:-1:-1;;;66474:37:0;;-1:-1:-1;;;;;6758:15:1;;;66474:37:0;;;6740:34:1;66505:4:0;6790:18:1;;;6783:43;66383:63:0;;-1:-1:-1;66459:12:0;;66474:15;;;;;6675:18:1;;66474:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;66524:11:0;;;;;:5;:11;;;;;:18;;-1:-1:-1;;66524:18:0;66538:4;66524:18;;;-1:-1:-1;;;66323:227:0:o;18940:249::-;19027:4;831:10;19085:37;19101:4;831:10;19116:5;19085:15;:37::i;:::-;19133:26;19143:4;19149:2;19153:5;19133:9;:26::i;:::-;19177:4;19170:11;;;18940:249;;;;;;:::o;65993:230::-;66053:25;58107:42;-1:-1:-1;;;;;66099:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66144:40;;-1:-1:-1;;;66144:40:0;;-1:-1:-1;;;;;6758:15:1;;;66144:40:0;;;6740:34:1;66178:4:0;6790:18:1;;;6783:43;66053:63:0;;-1:-1:-1;66129:12:0;;66144:18;;;;;6675::1;;66144:40:0;;;;;;;;;;;;;;;;;;;;;;;65072:131;-1:-1:-1;;;;;65176:18:0;;65133:7;65176:18;;;:12;:18;;;;;;;;65160:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:15;:35::i;41720:89::-;41775:26;831:10;41795:5;41775;:26::i;70381:107::-;2362:13;:11;:13::i;:::-;70454:26:::1;70475:4;70454:20;:26::i;72726:151::-:0;62778:8;;-1:-1:-1;;;;;62778:8:0;62764:10;:22;62756:44;;;;-1:-1:-1;;;62756:44:0;;;;;;;:::i;:::-;72827:19:::1;:42:::0;72726:151::o;17143:118::-;-1:-1:-1;;;;;17235:18:0;17208:7;17235:18;;;:9;:18;;;;;;;17143:118::o;3151:103::-;2362:13;:11;:13::i;:::-;3216:30:::1;3243:1;3216:18;:30::i;:::-;3151:103::o:0;72098:96::-;62778:8;;-1:-1:-1;;;;;62778:8:0;62764:10;:22;62756:44;;;;-1:-1:-1;;;62756:44:0;;;;;;;:::i;:::-;72168:7:::1;:18:::0;;::::1;::::0;;::::1;;;-1:-1:-1::0;;72168:18:0;;::::1;::::0;;;::::1;::::0;;72098:96::o;69793:91::-;2362:13;:11;:13::i;:::-;-1:-1:-1;;69847:9:0::1;:29:::0;69793:91::o;42138:161::-;42214:45;42230:7;831:10;42253:5;42214:15;:45::i;:::-;42270:21;42276:7;42285:5;42270;:21::i;:::-;42138:161;;:::o;70766:849::-;2362:13;:11;:13::i;:::-;70846:1:::1;70834:9;:13;70826:36;;;::::0;-1:-1:-1;;;70826:36:0;;7376:2:1;70826:36:0::1;::::0;::::1;7358:21:1::0;7415:2;7395:18;;;7388:30;-1:-1:-1;;;7434:18:1;;;7427:40;7484:18;;70826:36:0::1;7174:334:1::0;70826:36:0::1;70881:10;::::0;:15;70873:40:::1;;;::::0;-1:-1:-1;;;70873:40:0;;7715:2:1;70873:40:0::1;::::0;::::1;7697:21:1::0;7754:2;7734:18;;;7727:30;-1:-1:-1;;;7773:18:1;;;7766:42;7825:18;;70873:40:0::1;7513:336:1::0;70873:40:0::1;70980:12;70967:10;:25:::0;71068:3:::1;71052:13;17060:12:::0;;;16981:99;71052:13:::1;:19;;;;:::i;:::-;71040:9;:31:::0;71135:15:::1;71153:24;71171:4;71153:9;:24::i;:::-;71135:42;;71304:32;58107:42;-1:-1:-1::0;;;;;71322:11:0::1;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;71304:32::-;71398:49;71415:4;58107:42;71439:7;71398:8;:49::i;:::-;71508:99;::::0;-1:-1:-1;;;71508:99:0;;71557:4:::1;71508:99;::::0;::::1;8417:34:1::0;8467:18;;;8460:34;;;71573:1:0::1;8510:18:1::0;;;8503:34;;;8553:18;;;8546:34;71579:10:0::1;8596:19:1::0;;;8589:44;71591:15:0::1;8649:19:1::0;;;8642:35;58107:42:0::1;::::0;71508:22:::1;::::0;71538:9:::1;::::0;8351:19:1;;71508:99:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;70815:800;70766:849::o:0;64563:411::-;64610:7;64634:17;;64655:1;64634:22;64630:36;;-1:-1:-1;64665:1:0;;64563:411::o;64630:36::-;64681:19;;64704:1;64681:24;64677:38;;-1:-1:-1;64714:1:0;;64563:411::o;64677:38::-;64728:15;64746;:13;:15::i;:::-;64728:33;;64778:7;64789:1;64778:12;64774:26;;64799:1;64792:8;;;64563:411;:::o;64774:26::-;64813:15;64890:17;;64875:12;:32;;;;:::i;:::-;64852:19;;:56;;;;:::i;:::-;64831:17;;:78;;;;:::i;:::-;64813:96;;64939:7;64929;:17;:37;;64959:7;64929:37;;;64949:7;64929:37;64922:44;;;;64563:411;:::o;67878:935::-;67946:11;;67961:1;67946:16;67942:29;;67878:935;:::o;67942:29::-;68054:26;68083:16;:14;:16::i;:::-;68054:45;-1:-1:-1;68212:21:0;68250:12;;68246:128;;68301:61;68328:4;68335:8;68345:16;68301:18;:61::i;:::-;68279:83;;;;:::i;:::-;;;68246:128;68424:18;68446:1;68424:23;68420:36;;68449:7;;67878:935;:::o;68420:36::-;68567:11;;58581:4;68518:33;68539:12;68518:18;:33;:::i;:::-;:45;;;;:::i;:::-;68517:61;;;;:::i;:::-;68500:13;;:78;;;;;;;:::i;:::-;;;;;;;;68615:18;68589:22;;:44;;;;;;;:::i;:::-;;;;-1:-1:-1;;68701:1:0;68681:17;:21;68733:12;68713:17;:32;68763:42;;1949:25:1;;;68774:10:0;;68763:42;;1937:2:1;1922:18;68763:42:0;;;;;;;67931:882;;67878:935;:::o;66903:158::-;66947:30;66966:10;66947:18;:30::i;:::-;66998:10;67012:5;66990:19;;;:7;:19;;;;;;;;;:27;;-1:-1:-1;;66990:27:0;;;67035:18;;3242:51:1;;;67035:18:0;;3215::1;67035::0;;;;;;;;66903:158::o;16089:95::-;16136:13;16169:7;16162:14;;;;;:::i;17466:182::-;17535:4;831:10;17591:27;831:10;17608:2;17612:5;17591:9;:27::i;64184:213::-;64230:7;64250:21;64299:18;;64274:22;;:43;;;;:::i;:::-;64337:36;;-1:-1:-1;;;64337:36:0;;64367:4;64337:36;;;3242:51:1;64250:67:0;;-1:-1:-1;64250:67:0;;58217:42;;64337:21;;3215:18:1;;64337:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:52;;;;:::i;:::-;64330:59;;;64184:213;:::o;63902:118::-;63951:7;63996:16;:14;:16::i;:::-;63978:15;:13;:15::i;:::-;:34;;;;:::i;:::-;63971:41;;63902:118;:::o;71879:156::-;62778:8;;-1:-1:-1;;;;;62778:8:0;62764:10;:22;62756:44;;;;-1:-1:-1;;;62756:44:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;71960:23:0;::::1;71968:1;71960:23:::0;71952:44:::1;;;::::0;-1:-1:-1;;;71952:44:0;;9507:2:1;71952:44:0::1;::::0;::::1;9489:21:1::0;9546:1;9526:18;;;9519:29;-1:-1:-1;;;9564:18:1;;;9557:38;9612:18;;71952:44:0::1;9305:331:1::0;71952:44:0::1;72007:8;:20:::0;;-1:-1:-1;;;;;;72007:20:0::1;-1:-1:-1::0;;;;;72007:20:0;;;::::1;::::0;;;::::1;::::0;;71879:156::o;69560:162::-;2362:13;:11;:13::i;:::-;69644:10:::1;::::0;:15;69636:40:::1;;;::::0;-1:-1:-1;;;69636:40:0;;7715:2:1;69636:40:0::1;::::0;::::1;7697:21:1::0;7754:2;7734:18;;;7727:30;-1:-1:-1;;;7773:18:1;;;7766:42;7825:18;;69636:40:0::1;7513:336:1::0;69636:40:0::1;69689:25;::::0;-1:-1:-1;;;69689:25:0;;-1:-1:-1;;;;;9833:32:1;;69689:25:0::1;::::0;::::1;9815:51:1::0;9882:18;;;9875:34;;;69689:4:0::1;::::0;:13:::1;::::0;9788:18:1;;69689:25:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;69560:162:::0;;:::o;69932:370::-;2362:13;:11;:13::i;:::-;61756:4:::1;70041:21;::::0;::::1;;;70033:41;;;::::0;-1:-1:-1;;;70033:41:0;;10404:2:1;70033:41:0::1;::::0;::::1;10386:21:1::0;10443:1;10423:18;;;10416:29;-1:-1:-1;;;10461:18:1;;;10454:37;10508:18;;70033:41:0::1;10202:330:1::0;70033:41:0::1;61756:4;70093:22;::::0;::::1;;;70085:43;;;::::0;-1:-1:-1;;;70085:43:0;;10739:2:1;70085:43:0::1;::::0;::::1;10721:21:1::0;10778:1;10758:18;;;10751:29;-1:-1:-1;;;10796:18:1;;;10789:38;10844:18;;70085:43:0::1;10537:331:1::0;70085:43:0::1;61808:4;70147:32;::::0;::::1;;;70139:58;;;::::0;-1:-1:-1;;;70139:58:0;;11075:2:1;70139:58:0::1;::::0;::::1;11057:21:1::0;11114:2;11094:18;;;11087:30;-1:-1:-1;;;11133:18:1;;;11126:43;11186:18;;70139:58:0::1;10873:337:1::0;70139:58:0::1;70210:6;:16:::0;;-1:-1:-1;;70237:18:0;70210:16;::::1;::::0;;::::1;;-1:-1:-1::0;;70237:18:0;;-1:-1:-1;;;70237:18:0;;::::1;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;70266:28:0::1;-1:-1:-1::0;;;70266:28:0;;;::::1;;::::0;;;::::1;::::0;;69932:370::o;66650:154::-;66693:29;66711:10;66693:17;:29::i;:::-;66743:10;66735:19;;;;:7;:19;;;;;;;;;:26;;-1:-1:-1;;66735:26:0;66757:4;66735:26;;;66779:17;;3242:51:1;;;66779:17:0;;3215:18:1;66779:17:0;3096:203:1;72344:235:0;62778:8;;-1:-1:-1;;;;;62778:8:0;62764:10;:22;62756:44;;;;-1:-1:-1;;;62756:44:0;;;;;;;:::i;:::-;72459:16:::1;:14;:16::i;:::-;72439:17;:36:::0;72486:19:::1;:42:::0;72559:12:::1;72539:17;:32:::0;72344:235::o;67201:543::-;67307:16;67326:24;67344:4;67326:9;:24::i;:::-;67307:43;;67367:8;67379:1;67367:13;67363:26;;67382:7;67201:543;:::o;67363:26::-;67430:20;67453:56;67479:4;67486:8;67496:12;67453:17;:56::i;:::-;67599:12;;67430:79;;-1:-1:-1;67557:23:0;;61859:5;;67584:27;;-1:-1:-1;;;67599:12:0;;67583:46;67599:12;67430:79;67584:27;:::i;:::-;67583:46;;;;:::i;:::-;67557:72;-1:-1:-1;67646:19:0;;67642:95;;67690:8;;67682:43;;-1:-1:-1;;;;;67690:8:0;;;;67682:43;;;;;67709:15;;67690:8;67682:43;67690:8;67682:43;67709:15;67690:8;67682:43;;;;;;;;;;;;;;;;;;;;;67256:488;;;67201:543;:::o;72965:99::-;62778:8;;-1:-1:-1;;;;;62778:8:0;62764:10;:22;62756:44;;;;-1:-1:-1;;;62756:44:0;;;;;;;:::i;:::-;73055:1:::1;73035:17;:21:::0;72965:99::o;3409:220::-;2362:13;:11;:13::i;:::-;-1:-1:-1;;;;;3494:22:0;::::1;3490:93;;3540:31;::::0;-1:-1:-1;;;3540:31:0;;3568:1:::1;3540:31;::::0;::::1;3242:51:1::0;3215:18;;3540:31:0::1;3096:203:1::0;3490:93:0::1;3593:28;3612:8;3593:18;:28::i;36684:162::-:0;36794:43;;;-1:-1:-1;;;;;9833:32:1;;36794:43:0;;;9815:51:1;9882:18;;;;9875:34;;;36794:43:0;;;;;;;;;;9788:18:1;;;;36794:43:0;;;;;;;;-1:-1:-1;;;;;36794:43:0;-1:-1:-1;;;36794:43:0;;;36767:71;;36787:5;;36767:19;:71::i;22999:130::-;23084:37;23093:5;23100:7;23109:5;23116:4;23084:8;:37::i;44736:315::-;44034:1;44865:7;;:18;44861:88;;44907:30;;-1:-1:-1;;;44907:30:0;;;;;;;;;;;44861:88;44034:1;45026:7;:17;44736:315::o;77194:188::-;77267:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77249:15;;77267:22;;:15;:22::i;:::-;77302:12;;;:22;-1:-1:-1;77361:13:0;;77335:23;;;;:39;77194:188::o;24715:487::-;-1:-1:-1;;;;;17818:18:0;;;24815:24;17818:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;24882:37:0;;24878:317;;24959:5;24940:16;:24;24936:132;;;24992:60;;-1:-1:-1;;;24992:60:0;;-1:-1:-1;;;;;11435:32:1;;24992:60:0;;;11417:51:1;11484:18;;;11477:34;;;11527:18;;;11520:34;;;11390:18;;24992:60:0;11215:345:1;24936:132:0;25111:57;25120:5;25127:7;25155:5;25136:16;:24;25162:5;25111:8;:57::i;19574:308::-;-1:-1:-1;;;;;19658:18:0;;19654:88;;19700:30;;-1:-1:-1;;;19700:30:0;;19727:1;19700:30;;;3242:51:1;3215:18;;19700:30:0;3096:203:1;19654:88:0;-1:-1:-1;;;;;19756:16:0;;19752:88;;19796:32;;-1:-1:-1;;;19796:32:0;;19825:1;19796:32;;;3242:51:1;3215:18;;19796:32:0;3096:203:1;19752:88:0;19850:24;19858:4;19864:2;19868:5;19850:7;:24::i;76853:270::-;76920:7;76940:13;76972:5;:23;;;76956:13;;:39;;;;:::i;:::-;76940:55;-1:-1:-1;77006:14:0;77049:24;58581:4;77049:12;:24;:::i;:::-;77024:12;;:20;;77039:5;;77024:20;:::i;:::-;77023:51;;;;:::i;:::-;77006:68;;77109:6;77094:5;:12;;;:21;;;;:::i;:::-;77087:28;76853:270;-1:-1:-1;;;;76853:270:0:o;22235:211::-;-1:-1:-1;;;;;22306:21:0;;22302:91;;22351:30;;-1:-1:-1;;;22351:30:0;;22378:1;22351:30;;;3242:51:1;3215:18;;22351:30:0;3096:203:1;22302:91:0;22403:35;22411:7;22428:1;22432:5;22403:7;:35::i;2641:166::-;2522:7;2549:6;-1:-1:-1;;;;;2549:6:0;831:10;2701:23;2697:103;;2748:40;;-1:-1:-1;;;2748:40:0;;831:10;2748:40;;;3242:51:1;3215:18;;2748:40:0;3096:203:1;75191:177:0;75254:23;75272:4;75254:17;:23::i;:::-;-1:-1:-1;;;;;75290:19:0;;75312:5;75290:19;;;:13;:19;;;;;;;;;:27;;-1:-1:-1;;75290:27:0;;;75335:25;;3242:51:1;;;75335:25:0;;3215:18:1;75335:25:0;;;;;;;;75191:177;:::o;3789:191::-;3863:16;3882:6;;-1:-1:-1;;;;;3899:17:0;;;-1:-1:-1;;;;;;3899:17:0;;;;;;3932:40;;3882:6;;;;;;;3932:40;;3863:16;3932:40;3852:128;3789:191;:::o;80913:783::-;81014:7;81079:8;81091:1;81079:13;81075:27;;-1:-1:-1;81101:1:0;81094:8;;81075:27;81153:48;81204:341;;;;;;;;58107:42;-1:-1:-1;;;;;81263:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;81204:341:0;;;;;58217:42;81204:341;;;;;;;;81341:7;;;;;;;;;81204:341;;;;;;;;;;;;;;;;;;;81401:15;81204:341;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81204:341:0;;;;;81636:52;;-1:-1:-1;;;81636:52:0;;11852:13:1;;11848:22;;81636:52:0;;;11830:41:1;11919:17;;;11913:24;11909:33;;11887:20;;;11880:63;11991:17;;;11985:24;11981:39;;;11959:20;;;11952:69;12069:17;;;12063:24;12059:33;;12037:20;;;12030:63;12137:17;;12131:24;12109:20;;;12102:54;12200:17;;;12194:24;12172:20;;;12165:54;12263:17;;12257:24;12235:20;;;12228:54;12330:17;;;12324:24;12320:33;12298:20;;;12291:63;81153:392:0;;-1:-1:-1;57994:42:0;;81636:27;;81204:341;;11764:19:1;;81636:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81629:59;80913:783;-1:-1:-1;;;;;80913:783:0:o;76232:431::-;76351:28;76374:4;76351:22;:28::i;:::-;76347:41;;;76232:431;:::o;76347:41::-;76448:15;76458:4;76448:9;:15::i;:::-;76433:11;;:30;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;76583:18:0;;76561:19;76583:18;;;:12;:18;;;;;76614:12;76583:18;76614:5;:12::i;:::-;76654:1;76639:16;;-1:-1:-1;76232:431:0:o;75575:453::-;75694:28;75717:4;75694:22;:28::i;:::-;75689:42;;75575:453;:::o;75689:42::-;75776:15;75794;75804:4;75794:9;:15::i;:::-;75776:33;;75837:7;75822:11;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;75917:18:0;;;75895:19;75917:18;;;:12;:18;;;;;75948:22;;;76007:13;;75981:23;;;;:39;75575:453::o;80091:708::-;80187:7;80252:8;80264:1;80252:13;80248:27;;-1:-1:-1;80274:1:0;80267:8;;80248:27;80332:50;80349:4;58107:42;80373:8;80332;:50::i;:::-;80461:16;;;80475:1;80461:16;;;;;;;;80437:21;;80461:16;;;;;;;;;;-1:-1:-1;80461:16:0;80437:40;;80506:4;80488;80493:1;80488:7;;;;;;;;:::i;:::-;;;;;;:23;-1:-1:-1;;;;;80488:23:0;;;-1:-1:-1;;;;;80488:23:0;;;;;58107:42;-1:-1:-1;;;;;80532:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;80522:4;80527:1;80522:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;80522:23:0;;;:7;;;;;;;;;;;:23;80621:108;;-1:-1:-1;;;80621:108:0;;80587:21;;58107:42;;80621:57;;:108;;80679:8;;80689:12;;80703:4;;80709:2;;80713:15;;80621:108;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80773:18;80749:21;:42;;;;:::i;:::-;80742:49;80091:708;-1:-1:-1;;;;;;80091:708:0:o;39495:638::-;39919:23;39945:33;-1:-1:-1;;;;;39945:27:0;;39973:4;39945:27;:33::i;:::-;39919:59;;39993:10;:17;40014:1;39993:22;;:57;;;;;40031:10;40020:30;;;;;;;;;;;;:::i;:::-;40019:31;39993:57;39989:137;;;40074:40;;-1:-1:-1;;;40074:40:0;;-1:-1:-1;;;;;3260:32:1;;40074:40:0;;;3242:51:1;3215:18;;40074:40:0;3096:203:1;23980:443:0;-1:-1:-1;;;;;24093:19:0;;24089:91;;24136:32;;-1:-1:-1;;;24136:32:0;;24165:1;24136:32;;;3242:51:1;3215:18;;24136:32:0;3096:203:1;24089:91:0;-1:-1:-1;;;;;24194:21:0;;24190:92;;24239:31;;-1:-1:-1;;;24239:31:0;;24267:1;24239:31;;;3242:51:1;3215:18;;24239:31:0;3096:203:1;24190:92:0;-1:-1:-1;;;;;24292:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;:35;;;24338:78;;;;24389:7;-1:-1:-1;;;;;24373:31:0;24382:5;-1:-1:-1;;;;;24373:31:0;;24398:5;24373:31;;;;1949:25:1;;1937:2;1922:18;;1803:177;24373:31:0;;;;;;;;23980:443;;;;:::o;77926:1477::-;-1:-1:-1;;;;;78079:19:0;;;;;;:13;:19;;;;;;;;78078:20;78070:44;;;;-1:-1:-1;;;78070:44:0;;13808:2:1;78070:44:0;;;13790:21:1;13847:2;13827:18;;;13820:30;-1:-1:-1;;;13866:18:1;;;13859:41;13917:18;;78070:44:0;13606:335:1;78070:44:0;-1:-1:-1;;;;;78193:11:0;;78175:15;78193:11;;;:5;:11;;;;;;;;:40;;;;;78209:24;78230:2;78209:20;:24::i;:::-;78208:25;78193:40;78175:58;;78244:16;78264:26;78285:4;78264:20;:26::i;:::-;78263:27;:40;;;;-1:-1:-1;;;;;;78294:9:0;;;;;;:5;:9;;;;;;;;78263:40;78244:59;;78365:11;78408;:25;;78432:1;78408:25;;;78422:7;;-1:-1:-1;;;78422:7:0;;;;78408:25;78380:10;:23;;78402:1;78380:23;;;78393:6;;;;;;;78380:23;78379:55;;;;:::i;:::-;78365:69;;;-1:-1:-1;78447:17:0;61859:5;78468:12;78365:69;78468:6;:12;:::i;:::-;78467:31;;;;:::i;:::-;78447:51;-1:-1:-1;78511:28:0;78542:18;78447:51;78542:6;:18;:::i;:::-;78511:49;;78634:10;:28;;;;;78648:14;:12;:14::i;:::-;78630:80;;;78679:19;78695:2;78679:15;:19::i;:::-;78782:28;78807:2;78782:24;:28::i;:::-;78777:134;;78875:9;;78858:13;78868:2;78858:9;:13::i;:::-;78835:36;;:20;:36;:::i;:::-;:49;;78827:72;;;;-1:-1:-1;;;78827:72:0;;14323:2:1;78827:72:0;;;14305:21:1;14362:2;14342:18;;;14335:30;-1:-1:-1;;;14381:18:1;;;14374:40;14431:18;;78827:72:0;14121:334:1;78827:72:0;78981:13;;78977:91;;79011:45;79025:4;79039;79046:9;79011:13;:45::i;:::-;79140:11;79136:63;;;79168:19;79185:1;79168:16;:19::i;:::-;79251:45;79265:4;79271:2;79275:20;79251:13;:45::i;:::-;79350:18;79363:4;79350:12;:18::i;:::-;79379:16;79392:2;79379:12;:16::i;:::-;78003:1400;;;;;77926:1477;;;:::o;74602:277::-;74670:4;-1:-1:-1;;;;;74694:18:0;;;;:43;;-1:-1:-1;74724:4:0;-1:-1:-1;;;;;74716:21:0;;;74694:43;:87;;;;74761:1;74742:4;-1:-1:-1;;;;;74742:16:0;;:20;:38;;;;-1:-1:-1;;;;;;74767:13:0;;;;;;:7;:13;;;;;;;;74766:14;74742:38;74694:123;;;-1:-1:-1;;;;;;74798:19:0;;;;;;:13;:19;;;;;;;;74694:123;:177;;;-1:-1:-1;;;;;;;74821:50:0;:42;:50;;74602:277::o;31999:153::-;32074:12;32106:38;32128:6;32136:4;32142:1;32106:21;:38::i;73997:146::-;74063:4;74095;-1:-1:-1;;;;;74087:21:0;;;;:48;;-1:-1:-1;;;;;;;74112:23:0;58107:42;74112:23;;73997:146::o;73382:117::-;73481:10;;73468;;73428:4;;73468:23;;73481:10;;;;;73468:23;:::i;:::-;73452:12;:39;;73445:46;;73382:117;:::o;74949:167::-;75007:24;75026:4;75007:18;:24::i;:::-;-1:-1:-1;;;;;75044:19:0;;;;;;:13;:19;;;;;;;;;:26;;-1:-1:-1;;75044:26:0;75066:4;75044:26;;;75088:20;;3242:51:1;;;75088:20:0;;3215:18:1;75088:20:0;3096:203:1;73710:188:0;73780:4;73812;-1:-1:-1;;;;;73804:21:0;;;;:48;;-1:-1:-1;58107:42:0;-1:-1:-1;;;;;73829:23:0;;;73804:48;:63;;;-1:-1:-1;;;;;;73856:11:0;;;;;;:5;:11;;;;;;;;73804:63;:86;;;-1:-1:-1;;;;;;;73871:19:0;;;;;:13;:19;;;;;;;;;73710:188::o;20206:1135::-;-1:-1:-1;;;;;20296:18:0;;20292:552;;20450:5;20434:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;20292:552:0;;-1:-1:-1;20292:552:0;;-1:-1:-1;;;;;20510:15:0;;20488:19;20510:15;;;:9;:15;;;;;;20544:19;;;20540:117;;;20591:50;;-1:-1:-1;;;20591:50:0;;-1:-1:-1;;;;;11435:32:1;;20591:50:0;;;11417:51:1;11484:18;;;11477:34;;;11527:18;;;11520:34;;;11390:18;;20591:50:0;11215:345:1;20540:117:0;-1:-1:-1;;;;;20780:15:0;;;;;;:9;:15;;;;;20798:19;;;;20780:37;;20292:552;-1:-1:-1;;;;;20860:16:0;;20856:435;;21026:12;:21;;;;;;;20856:435;;;-1:-1:-1;;;;;21242:13:0;;;;;;:9;:13;;;;;:22;;;;;;20856:435;21323:2;-1:-1:-1;;;;;21308:25:0;21317:4;-1:-1:-1;;;;;21308:25:0;;21327:5;21308:25;;;;1949::1;;1937:2;1922:18;;1803:177;21308:25:0;;;;;;;;20206:1135;;;:::o;79655:325::-;79714:28;79737:4;79714:22;:28::i;:::-;79710:41;;;79655:325;:::o;79710:41::-;79763:15;79781;79791:4;79781:9;:15::i;:::-;-1:-1:-1;;;;;79831:18:0;;79809:19;79831:18;;;:12;:18;;;;;79890:12;;79876:11;;79763:33;;-1:-1:-1;79831:18:0;;79763:33;;79876:26;;;:::i;:::-;:36;;;;:::i;:::-;79862:11;:50;79925:12;79931:5;79925;:12::i;:::-;79950:22;-1:-1:-1;79655:325:0:o;32487:398::-;32586:12;32639:5;32615:21;:29;32611:110;;;32668:41;;-1:-1:-1;;;32668:41:0;;32703:4;32668:41;;;3242:51:1;3215:18;;32668:41:0;3096:203:1;32611:110:0;32732:12;32746:23;32773:6;-1:-1:-1;;;;;32773:11:0;32792:5;32799:4;32773:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32731:73;;;;32822:55;32849:6;32857:7;32866:10;34111:12;34141:7;34136:417;;34165:19;34173:10;34165:7;:19::i;:::-;34136:417;;;34393:17;;:22;:49;;;;-1:-1:-1;;;;;;34419:18:0;;;:23;34393:49;34389:121;;;34470:24;;-1:-1:-1;;;34470:24:0;;-1:-1:-1;;;;;3260:32:1;;34470:24:0;;;3242:51:1;3215:18;;34470:24:0;3096:203:1;34389:121:0;-1:-1:-1;34531:10:0;34524:17;;35113:528;35246:17;;:21;35242:392;;35478:10;35472:17;35535:15;35522:10;35518:2;35514:19;35507:44;35242:392;35605:17;;-1:-1:-1;;;35605:17:0;;;;;;;;;;;14:139:1;-1:-1:-1;;;;;97:31:1;;87:42;;77:70;;143:1;140;133:12;158:269;231:6;284:2;272:9;263:7;259:23;255:32;252:52;;;300:1;297;290:12;252:52;339:9;326:23;358:39;391:5;358:39;:::i;432:250::-;517:1;527:113;541:6;538:1;535:13;527:113;;;617:11;;;611:18;598:11;;;591:39;563:2;556:10;527:113;;;-1:-1:-1;;674:1:1;656:16;;649:27;432:250::o;687:396::-;836:2;825:9;818:21;799:4;868:6;862:13;911:6;906:2;895:9;891:18;884:34;927:79;999:6;994:2;983:9;979:18;974:2;966:6;962:15;927:79;:::i;:::-;1067:2;1046:15;-1:-1:-1;;1042:29:1;1027:45;;;;1074:2;1023:54;;687:396;-1:-1:-1;;687:396:1:o;1283:323::-;1351:6;1359;1412:2;1400:9;1391:7;1387:23;1383:32;1380:52;;;1428:1;1425;1418:12;1380:52;1467:9;1454:23;1486:39;1519:5;1486:39;:::i;:::-;1544:5;1596:2;1581:18;;;;1568:32;;-1:-1:-1;;;1283:323:1:o;2245:472::-;2322:6;2330;2338;2391:2;2379:9;2370:7;2366:23;2362:32;2359:52;;;2407:1;2404;2397:12;2359:52;2446:9;2433:23;2465:39;2498:5;2465:39;:::i;:::-;2523:5;-1:-1:-1;2580:2:1;2565:18;;2552:32;2593:41;2552:32;2593:41;:::i;:::-;2245:472;;2653:7;;-1:-1:-1;;;2707:2:1;2692:18;;;;2679:32;;2245:472::o;2911:180::-;2970:6;3023:2;3011:9;3002:7;2998:23;2994:32;2991:52;;;3039:1;3036;3029:12;2991:52;-1:-1:-1;3062:23:1;;2911:180;-1:-1:-1;2911:180:1:o;3304:161::-;3371:20;;3431:8;3420:20;;3410:31;;3400:59;;3455:1;3452;3445:12;3400:59;3304:161;;;:::o;3470:184::-;3528:6;3581:2;3569:9;3560:7;3556:23;3552:32;3549:52;;;3597:1;3594;3587:12;3549:52;3620:28;3638:9;3620:28;:::i;3887:328::-;3961:6;3969;3977;4030:2;4018:9;4009:7;4005:23;4001:32;3998:52;;;4046:1;4043;4036:12;3998:52;4069:28;4087:9;4069:28;:::i;:::-;4059:38;;4116:37;4149:2;4138:9;4134:18;4116:37;:::i;:::-;4106:47;;4172:37;4205:2;4194:9;4190:18;4172:37;:::i;:::-;4162:47;;3887:328;;;;;:::o;4220:404::-;4288:6;4296;4349:2;4337:9;4328:7;4324:23;4320:32;4317:52;;;4365:1;4362;4355:12;4317:52;4404:9;4391:23;4423:39;4456:5;4423:39;:::i;:::-;4481:5;-1:-1:-1;4538:2:1;4523:18;;4510:32;4551:41;4510:32;4551:41;:::i;:::-;4611:7;4601:17;;;4220:404;;;;;:::o;5428:184::-;5498:6;5551:2;5539:9;5530:7;5526:23;5522:32;5519:52;;;5567:1;5564;5557:12;5519:52;-1:-1:-1;5590:16:1;;5428:184;-1:-1:-1;5428:184:1:o;5617:380::-;5696:1;5692:12;;;;5739;;;5760:61;;5814:4;5806:6;5802:17;5792:27;;5760:61;5867:2;5859:6;5856:14;5836:18;5833:38;5830:161;;5913:10;5908:3;5904:20;5901:1;5894:31;5948:4;5945:1;5938:15;5976:4;5973:1;5966:15;5830:161;;5617:380;;;:::o;6002:127::-;6063:10;6058:3;6054:20;6051:1;6044:31;6094:4;6091:1;6084:15;6118:4;6115:1;6108:15;6134:125;6199:9;;;6220:10;;;6217:36;;;6233:18;;:::i;6264:259::-;6334:6;6387:2;6375:9;6366:7;6362:23;6358:32;6355:52;;;6403:1;6400;6393:12;6355:52;6435:9;6429:16;6454:39;6487:5;6454:39;:::i;6837:332::-;7039:2;7021:21;;;7078:1;7058:18;;;7051:29;-1:-1:-1;;;7111:2:1;7096:18;;7089:39;7160:2;7145:18;;6837:332::o;7854:217::-;7894:1;7920;7910:132;;7964:10;7959:3;7955:20;7952:1;7945:31;7999:4;7996:1;7989:15;8027:4;8024:1;8017:15;7910:132;-1:-1:-1;8056:9:1;;7854:217::o;8688:306::-;8776:6;8784;8792;8845:2;8833:9;8824:7;8820:23;8816:32;8813:52;;;8861:1;8858;8851:12;8813:52;8890:9;8884:16;8874:26;;8940:2;8929:9;8925:18;8919:25;8909:35;;8984:2;8973:9;8969:18;8963:25;8953:35;;8688:306;;;;;:::o;8999:128::-;9066:9;;;9087:11;;;9084:37;;;9101:18;;:::i;9132:168::-;9205:9;;;9236;;9253:15;;;9247:22;;9233:37;9223:71;;9274:18;;:::i;9920:277::-;9987:6;10040:2;10028:9;10019:7;10015:23;10011:32;10008:52;;;10056:1;10053;10046:12;10008:52;10088:9;10082:16;10141:5;10134:13;10127:21;10120:5;10117:32;10107:60;;10163:1;10160;10153:12;12497:127;12558:10;12553:3;12549:20;12546:1;12539:31;12589:4;12586:1;12579:15;12613:4;12610:1;12603:15;12629:972;12883:4;12931:3;12920:9;12916:19;12962:6;12951:9;12944:25;12988:2;13026:6;13021:2;13010:9;13006:18;12999:34;13069:3;13064:2;13053:9;13049:18;13042:31;13093:6;13128;13122:13;13159:6;13151;13144:22;13197:3;13186:9;13182:19;13175:26;;13236:2;13228:6;13224:15;13210:29;;13257:1;13267:195;13281:6;13278:1;13275:13;13267:195;;;13346:13;;-1:-1:-1;;;;;13342:39:1;13330:52;;13437:15;;;;13402:12;;;;13378:1;13296:9;13267:195;;;-1:-1:-1;;;;;;;13518:32:1;;;;13513:2;13498:18;;13491:60;-1:-1:-1;;;13582:3:1;13567:19;13560:35;13479:3;12629:972;-1:-1:-1;;;12629:972:1:o;13946:170::-;14013:8;14041:10;;;14053;;;14037:27;;14076:11;;;14073:37;;;14090:18;;:::i;:::-;14073:37;13946:170;;;;:::o;14460:287::-;14589:3;14627:6;14621:13;14643:66;14702:6;14697:3;14690:4;14682:6;14678:17;14643:66;:::i;:::-;14725:16;;;;;14460:287;-1:-1:-1;;14460:287:1:o

Swarm Source

ipfs://7cf7062cb623c26255eb2d98ae2e3abec8ceb2d3f53b33f6ce8296bbb7dc9655
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.