ETH Price: $2,950.33 (-0.08%)
 

Overview

Max Total Supply

20,000,000 RYIU

Holders

3,672 (0.00%)

Market

Price

$0.0022 @ 0.000001 ETH

Onchain Market Cap

-

Circulating Supply Market Cap

$33,858.00

Other Info

Token Contract (WITH 9 Decimals)

Balance
626.44505613 RYIU

Value
$1.40 ( ~0.000474523051518014 ETH) [0.0031%]
0xaD01C20d5886137e056775af56915de824c8fCe5
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Ryi Unity is a decentralized applications builder focused on providing innovative solutions for the decentralized world.

Market

Volume (24H):$3,664.53
Market Capitalization:$33,858.00
Circulating Supply:15,140,076.00 RYIU
Market Data Source: Coinmarketcap

Contract Source Code Verified (Exact Match)

Contract Name:
RyiuToken

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.17;

import "@openzeppelin/contracts/access/Ownable.sol";
import "./libraries/AccountValidator.sol";
import "./libraries/AntiWhale.sol";
import "./libraries/Recover.sol";
import "./libraries/TaxToken.sol";

contract RyiuToken is Ownable, AccountValidator, Recover, AntiWhale, TaxToken {
    string private constant NAME = "RYIU Token";
    string private constant SYMBOL = "RYIU";
    uint8 private constant DECIMALS = 9;
    uint256 private constant SUPPLY = 20 * 10 ** 6 * 10 ** 9;

    constructor(
        address swapRouter_,
        FeeConfiguration memory feeConfiguration_
    )
        ERC20Base(NAME, SYMBOL, DECIMALS)
        AntiWhale(SUPPLY / 100) /* 1% of supply */
        TaxToken(true, (SUPPLY * 5) / 10000 /* 0.05% of supply */, swapRouter_, feeConfiguration_)
        RewardToken(SUPPLY)
    {
        // configure addresses excluded from rewards
        _setIsExcludedFromRewards(swapPair, true);
        _setIsExcludedFromRewards(BURN_ADDRESS, true);

        // configure addresses excluded from antiwhale
        _setIsExcludedFromAntiWhale(swapPair, true);
        _setIsExcludedFromAntiWhale(BURN_ADDRESS, true);
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override (ERC20Base, AccountValidator) {
        super._beforeTokenTransfer(from, to, amount);
    }

    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override(ERC20Base, AntiWhale) {
        super._afterTokenTransfer(from, to, amount);
    }
}

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

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. 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;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @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 {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _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 {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _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);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

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

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

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

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

pragma solidity ^0.8.0;

/**
 * @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 amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        bytes32[] memory store = _values(set._inner);
        bytes32[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

pragma solidity >=0.5.0;

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;
}

pragma solidity >=0.6.2;

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

    function addLiquidity(
        address tokenA,
        address tokenB,
        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);
}

pragma solidity >=0.6.2;

import './IUniswapV2Router01.sol';

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;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.17;

import "@openzeppelin/contracts/access/Ownable.sol";
import "./ERC20Base.sol";

/**
 * @dev allow the owner to block an address
 */
abstract contract AccountValidator is Ownable, ERC20Base {
    mapping(address => bool) private _denied;

    event AddressDenied(address indexed account, bool denied);

    modifier notDenied(address account) {
        require(!_denied[account], "Address denied");
        _;
    }

    function _setIsDenied(address account, bool denied) internal {
        _denied[account] = denied;
        emit AddressDenied(account, denied);
    }

    function isAccountDenied(address account) public view returns (bool) {
        return _denied[account];
    }

    function setIsAccountDenied(address account, bool denied) external onlyOwner {
        require(_denied[account] != denied, "Already set");
        _setIsDenied(account, denied);
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override notDenied(from) notDenied(to) {
        super._beforeTokenTransfer(from, to, amount);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.17;

import "@openzeppelin/contracts/access/Ownable.sol";
import "./ERC20Base.sol";

/**
 * @dev limit the maximum number of tokens per wallet
 */
abstract contract AntiWhale is Ownable, ERC20Base {
    uint256 public maxTokenPerWallet;
    mapping(address => bool) private _excluded;

    event ExcludedFromAntiWhale(address indexed account, bool excluded);
    event MaxTokenPerWalletUpdated(uint256 amount);

    constructor(uint256 maxTokenPerWallet_) {
        maxTokenPerWallet = maxTokenPerWallet_;

        _setIsExcludedFromAntiWhale(_msgSender(), true);
        _setIsExcludedFromAntiWhale(address(this), true);
    }

    function _setIsExcludedFromAntiWhale(address account, bool excluded) internal {
        _excluded[account] = excluded;
        emit ExcludedFromAntiWhale(account, excluded);
    }

    function isExcludedFromAntiWhale(address account) public view returns (bool) {
        return _excluded[account];
    }

    function setIsExcludedFromAntiWhale(address account, bool excluded) external onlyOwner {
        require(_excluded[account] != excluded, "Already set");
        _setIsExcludedFromAntiWhale(account, excluded);
    }

    function setMaxTokenPerWallet(uint256 amount) external onlyOwner {
        uint256 supply = totalSupply();

        if (amount == 0) amount = supply; // set to 0 to disable
        require(amount > (supply * 5) / 1000, "Amount too low"); // min 0.5% of supply

        maxTokenPerWallet = amount;
        emit MaxTokenPerWalletUpdated(amount);
    }

    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual override {
        if (!isExcludedFromAntiWhale(to)) {
            require(balanceOf(to) <= maxTokenPerWallet, "AntiWhale: balance too high");
        }
        super._afterTokenTransfer(from, to, amount);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.17;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "@openzeppelin/contracts/utils/Context.sol";

/**
 * @dev abstract implementation of @openzeppelin's ERC20, without balance/supply management
 */
abstract contract ERC20Base is Context, IERC20, IERC20Metadata {
    mapping(address => mapping(address => uint256)) private _allowances;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    constructor(string memory name_, string memory symbol_, uint8 decimals_) {
        _name = name_;
        _symbol = symbol_;
        _decimals = decimals_;
    }

    function name() public view virtual override returns (string memory) {
        return _name;
    }

    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

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

    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

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

    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

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

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = balanceOf(from);
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");

        _executeTransfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

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

    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

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

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

    function _executeTransfer(address from, address to, uint256 amount) internal virtual;

    function totalSupply() public view virtual override returns (uint256);

    function balanceOf(address account) public view virtual override returns (uint256);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.17;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

contract FeeDistributor is Ownable {
    using EnumerableSet for EnumerableSet.AddressSet;

    EnumerableSet.AddressSet private _collectors;
    mapping(address => uint256) private _shares;
    uint256 public totalFeeCollectorsShares;

    event FeeCollectorAdded(address indexed account, uint256 share);
    event FeeCollectorUpdated(address indexed account, uint256 oldShare, uint256 newShare);
    event FeeCollectorRemoved(address indexed account);
    event FeeCollected(address indexed receiver, uint256 amount);

    function isFeeCollector(address account) public view returns (bool) {
        return _collectors.contains(account);
    }

    function feeCollectorShare(address account) public view returns (uint256) {
        return _shares[account];
    }

    function _addFeeCollector(address account, uint256 share) internal {
        require(!_collectors.contains(account), "Already fee collector");
        require(share > 0, "Invalid share");

        _collectors.add(account);
        _shares[account] = share;
        totalFeeCollectorsShares += share;

        emit FeeCollectorAdded(account, share);
    }

    function _removeFeeCollector(address account) internal {
        require(_collectors.contains(account), "Not fee collector");
        _collectors.remove(account);
        totalFeeCollectorsShares -= _shares[account];
        delete _shares[account];

        emit FeeCollectorRemoved(account);
    }

    function addFeeCollector(address account, uint256 share) external onlyOwner {
        _addFeeCollector(account, share);
    }

    function removeFeeCollector(address account) external onlyOwner {
        _removeFeeCollector(account);
    }

    function updateFeeCollectorShare(address account, uint256 share) external onlyOwner {
        require(_collectors.contains(account), "Not fee collector");
        require(share > 0, "Invalid share");

        uint256 oldShare = _shares[account];
        totalFeeCollectorsShares -= oldShare;

        _shares[account] = share;
        totalFeeCollectorsShares += share;

        emit FeeCollectorUpdated(account, oldShare, share);
    }

    function _distributeFees(uint256 amount) internal returns (bool) {
        if (amount == 0) return false;
        if (totalFeeCollectorsShares == 0) return false;

        uint256 distributed = 0;
        uint256 len = _collectors.length();
        for (uint256 i = 0; i < len; i++) {
            address collector = _collectors.at(i);
            uint256 share = i == len - 1
                ? amount - distributed
                : (amount * _shares[collector]) / totalFeeCollectorsShares;

            payable(collector).transfer(share);
            emit FeeCollected(collector, share);

            distributed += share;
        }

        return true;
    }

    function distributeFees(uint256 amount) external onlyOwner {
        require(amount <= address(this).balance, "Not enough balance");
        _distributeFees(amount);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.17;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract Recover is Ownable {
    event TokenRecovered(address indexed token, uint256 amount);

    function recoverTokens(address token, uint256 amount) external onlyOwner {
        require(amount > 0, "Invalid amount");

        if (token == address(0)) {
            payable(msg.sender).transfer(amount);
        } else {
            require(IERC20(token).transfer(msg.sender, amount));
        }

        emit TokenRecovered(token, amount);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.17;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "./ERC20Base.sol";

abstract contract RewardToken is Ownable, ERC20Base {
    using EnumerableSet for EnumerableSet.AddressSet;

    uint256 private constant MAX = ~uint256(0);

    uint256 private _tTotal;
    uint256 private _rTotal;
    uint256 private _tFeeTotal;

    mapping(address => uint256) private _rOwned;
    mapping(address => uint256) private _tOwned;

    EnumerableSet.AddressSet private _excluded;

    event ExcludedFromRewards(address indexed account, bool excluded);
    event TransferRewards(address indexed from, uint256 amount);

    constructor(uint256 supply_) {
        _tTotal = supply_;
        _rTotal = (MAX - (MAX % _tTotal));
        _rOwned[_msgSender()] = _rTotal;
        emit Transfer(address(0), _msgSender(), _tTotal);
    }

    function totalSupply() public view override returns (uint256) {
        return _tTotal;
    }

    function totalRewardFees() public view returns (uint256) {
        return _tFeeTotal;
    }

    function balanceOf(address account) public view override returns (uint256) {
        if (_excluded.contains(account)) return _tOwned[account];
        return tokenFromReflection(_rOwned[account]);
    }

    function isExcludedFromRewards(address account) public view returns (bool) {
        return _excluded.contains(account);
    }

    function _setIsExcludedFromRewards(address account, bool excluded) internal {
        require(_excluded.contains(account) != excluded, "Already set");

        if (excluded) {
            if (_rOwned[account] > 0) {
                _tOwned[account] = tokenFromReflection(_rOwned[account]);
            }
            _excluded.add(account);
        } else {
            _tOwned[account] = 0;
            _excluded.remove(account);
        }

        emit ExcludedFromRewards(account, excluded);
    }

    function setIsExcludedFromRewards(address account, bool excluded) external onlyOwner {
        _setIsExcludedFromRewards(account, excluded);
    }

    function tokenFromReflection(uint256 rAmount) private view returns (uint256) {
        require(rAmount <= _rTotal, "Amount must be less than total reflections");
        uint256 currentRate = _getRate();
        return rAmount / currentRate;
    }

    function _executeTransfer(address from, address to, uint256 amount) internal virtual override {
        _executeTokenTransfer(from, to, amount, amount / 100);
    }

    function _executeTokenTransfer(
        address sender,
        address recipient,
        uint256 amount,
        uint256 rewards
    ) internal {
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(
            amount,
            rewards
        );
        require(_rOwned[sender] >= rAmount, "ERC20: transfer amount exceeds balance");

        _rOwned[sender] -= rAmount;
        _rOwned[recipient] += rTransferAmount;
        if (_excluded.contains(sender)) {
            require(_tOwned[sender] >= amount, "ERC20: transfer amount exceeds balance");
            _tOwned[sender] -= amount;
        }
        if (_excluded.contains(recipient)) _tOwned[recipient] += tTransferAmount;

        _reflectFee(rFee, tFee);
        emit Transfer(sender, recipient, tTransferAmount);
        if (rewards > 0) {
            emit TransferRewards(sender, rewards);
        }
    }

    function _reflectFee(uint256 rFee, uint256 tFee) private {
        _rTotal -= rFee;
        _tFeeTotal += tFee;
    }

    function _getValues(
        uint256 tAmount,
        uint256 tFee
    ) private view returns (uint256, uint256, uint256, uint256, uint256) {
        uint256 currentRate = _getRate();
        uint256 rAmount = tAmount * currentRate;
        uint256 rFee = tFee * currentRate;
        uint256 rTransferAmount = rAmount - rFee;
        return (rAmount, rTransferAmount, rFee, tAmount - tFee, tFee);
    }

    function _getRate() private view returns (uint256) {
        (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
        return rSupply / tSupply;
    }

    function _getCurrentSupply() private view returns (uint256, uint256) {
        uint256 rSupply = _rTotal;
        uint256 tSupply = _tTotal;
        for (uint256 i = 0; i < _excluded.length(); i++) {
            address addr = _excluded.at(i);
            if (_rOwned[addr] > rSupply || _tOwned[addr] > tSupply) return (_rTotal, _tTotal);
            rSupply -= _rOwned[addr];
            tSupply -= _tOwned[addr];
        }
        if (rSupply < _rTotal / _tTotal) return (_rTotal, _tTotal);
        return (rSupply, tSupply);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.17;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "./FeeDistributor.sol";
import "./RewardToken.sol";

/*
 * TaxToken
 * Based on the configuration, a part of each transaction (buy, sell, transfer) is burned, added to the liquidity pool , used for yield rewards and sent to the collectors (ie team)
 */
abstract contract TaxToken is Ownable, FeeDistributor, RewardToken {
    struct FeeConfiguration {
        uint16 buyFees; // fees applied during buys, from 0 to 2000 (ie, 100 = 1%)
        uint16 sellFees; // fees applied during sells, from 0 to 2000 (ie, 100 = 1%)
        uint16 transferFees; // fees applied during transfers, from 0 to 2000 (ie, 100 = 1%)
        uint16 burnFeeRatio; // from 0 to 10000 (ie 8000 = 80% of the fee collected are burned)
        uint16 rewardsFeeRatio; // from 0 to 10000 (ie 8000 = 80% of the fee collected are used for passive rewards)
        uint16 liquidityFeeRatio; // from 0 to 10000 (ie 8000 = 80% of the fee collected are added back to liquidity)
        uint16 collectorsFeeRatio; // from 0 to 10000 (ie 8000 = 80% of the fee collected are sent to fee collectors)
    }

    address public constant BURN_ADDRESS = address(0x000000000000000000000000000000000000dEaD);
    uint16 public constant MAX_FEE = 2000; // max 20% fees
    uint16 public constant FEE_PRECISION = 10000;

    // swap config
    IUniswapV2Router02 public swapRouter;
    address public swapPair;
    address public liquidityOwner;

    // fees
    bool private _processingFees;
    bool public autoProcessFees;
    uint256 public numTokensToSwap; // amount of tokens to collect before processing fees (default to 0.05% of supply)
    FeeConfiguration public feeConfiguration;

    uint256 public tradeStartBlock;

    mapping(address => bool) private _excludedFromFees;
    mapping(address => bool) private _lpPools;
    mapping(address => bool) private _bots;

    event FeeConfigurationUpdated(FeeConfiguration configuration);
    event SwapRouterUpdated(address indexed router, address indexed pair);
    event ExcludedFromFees(address indexed account, bool excluded);
    event SetLpPool(address indexed pairAddress, bool isLp);
    event SetIsBot(address indexed account, bool isBot);

    modifier lockTheSwap() {
        _processingFees = true;
        _;
        _processingFees = false;
    }

    constructor(
        bool autoProcessFees_,
        uint256 numTokensToSwap_,
        address swapRouter_,
        FeeConfiguration memory feeConfiguration_
    ) {
        numTokensToSwap = numTokensToSwap_;
        autoProcessFees = autoProcessFees_;

        liquidityOwner = _msgSender();

        // Create a uniswap pair for this new token
        swapRouter = IUniswapV2Router02(swapRouter_);
        swapPair = IUniswapV2Factory(swapRouter.factory()).createPair(address(this), swapRouter.WETH());
        _lpPools[address(swapPair)] = true;

        // configure addresses excluded from fee
        _setIsExcludedFromFees(_msgSender(), true);
        _setIsExcludedFromFees(address(this), true);

        // configure fees
        _setFeeConfiguration(feeConfiguration_);
    }

    // receive ETH when swaping
    receive() external payable {}

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

    function _setIsExcludedFromFees(address account, bool excluded) internal {
        require(_excludedFromFees[account] != excluded, "Already set");
        _excludedFromFees[account] = excluded;
        emit ExcludedFromFees(account, excluded);
    }

    function setIsExcludedFromFees(address account, bool excluded) external onlyOwner {
        _setIsExcludedFromFees(account, excluded);
    }

    function isLpPool(address pairAddress) public view returns (bool) {
        return _lpPools[pairAddress];
    }

    function setIsLpPool(address pairAddress, bool isLp) external onlyOwner {
        require(_lpPools[pairAddress] != isLp, "Already set");
        _lpPools[pairAddress] = isLp;
        emit SetLpPool(pairAddress, isLp);
    }

    function isBot(address account) public view returns (bool) {
        return _bots[account];
    }

    function _setIsBot(address account, bool bot) internal {
        require(_bots[account] != bot, "Already set");
        _bots[account] = bot;
        emit SetIsBot(account, bot);
    }

    function setIsBot(address account, bool bot) external onlyOwner {
        _setIsBot(account, bot);
    }

    function updateSwapRouter(address _newRouter) external onlyOwner {
        require(_newRouter != address(0), "Invalid router");

        swapRouter = IUniswapV2Router02(_newRouter);
        IUniswapV2Factory factory = IUniswapV2Factory(swapRouter.factory());
        require(address(factory) != address(0), "Invalid factory");

        address weth = swapRouter.WETH();
        swapPair = factory.getPair(address(this), weth);
        if (swapPair == address(0)) {
            swapPair = factory.createPair(address(this), weth);
        }

        require(swapPair != address(0), "Invalid pair address.");
        emit SwapRouterUpdated(address(swapRouter), swapPair);
    }

    function _setFeeConfiguration(FeeConfiguration memory configuration) private {
        require(configuration.buyFees <= MAX_FEE, "Invalid buy fee");
        require(configuration.sellFees <= MAX_FEE, "Invalid sell fee");
        require(configuration.transferFees <= MAX_FEE, "Invalid transfer fee");

        uint16 totalShare = configuration.burnFeeRatio +
            configuration.rewardsFeeRatio +
            configuration.liquidityFeeRatio +
            configuration.collectorsFeeRatio;
        require(totalShare == 0 || totalShare == FEE_PRECISION, "Invalid fee share");

        feeConfiguration = configuration;
        emit FeeConfigurationUpdated(configuration);
    }

    function setFeeConfiguration(FeeConfiguration calldata configuration) external onlyOwner {
        _setFeeConfiguration(configuration);
    }

    function _processFees(uint256 tokenAmount, uint256 minAmountOut) private lockTheSwap {
        uint256 contractTokenBalance = balanceOf(address(this));
        if (contractTokenBalance >= tokenAmount) {
            uint256 liquidityAmount = (tokenAmount * feeConfiguration.liquidityFeeRatio) /
                (FEE_PRECISION - feeConfiguration.burnFeeRatio - feeConfiguration.rewardsFeeRatio);
            uint256 liquidityTokens = liquidityAmount / 2;

            uint256 collectorsAmount = tokenAmount - liquidityAmount;
            uint256 liquifyAmount = liquidityAmount - liquidityTokens + collectorsAmount;

            // swap tokens
            if (liquifyAmount > 0) {
                // capture the contract's current balance.
                uint256 initialBalance = address(this).balance;

                _swapTokensForEth(liquifyAmount, minAmountOut);

                // how much did we just swap into?
                uint256 swapBalance = address(this).balance - initialBalance;

                // add liquidity
                uint256 liquidityETH = (swapBalance * liquidityTokens) / liquifyAmount;
                if (liquidityETH > 0) {
                    _addLiquidity(liquidityTokens, liquidityETH);
                }
            }

            // send remaining ETH to fee collectors
            _distributeFees(address(this).balance);
        }
    }

    function processFees(uint256 amount, uint256 minAmountOut) external onlyOwner {
        require(amount <= balanceOf(address(this)), "Amount too high");
        _processFees(amount, minAmountOut);
    }

    function setAutoprocessFees(bool autoProcess) external onlyOwner {
        require(autoProcessFees != autoProcess, "Already set");
        autoProcessFees = autoProcess;
    }

    function setNumTokensToSwap(uint256 amount) external onlyOwner {
        numTokensToSwap = amount;
    }

    function setLiquidityOwner(address newOwner) external onlyOwner {
        liquidityOwner = newOwner;
    }

    /// @dev Swap tokens for eth
    function _swapTokensForEth(uint256 tokenAmount, uint256 minAmountOut) private {
        // generate the swap pair path of token -> weth
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = swapRouter.WETH();

        _approve(address(this), address(swapRouter), tokenAmount);

        // make the swap
        swapRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            minAmountOut,
            path,
            address(this),
            block.timestamp
        );
    }

    /// @dev Add liquidity
    function _addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
        // approve token transfer to cover all possible scenarios
        _approve(address(this), address(swapRouter), tokenAmount);

        // add the liquidity
        swapRouter.addLiquidityETH{value: ethAmount}(
            address(this),
            tokenAmount,
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            liquidityOwner,
            block.timestamp
        );
    }

    function _executeTransfer(address from, address to, uint256 amount) internal override {
        require(amount > 0, "Transfer <= 0");

        uint256 taxFee = 0;
        bool processFee = !_processingFees && autoProcessFees && tradeStartBlock > 0;
        bool bot = _bots[from] || _bots[to];

        if (!_processingFees) {
            bool fromExcluded = isExcludedFromFees(from);
            bool toExcluded = isExcludedFromFees(to);

            bool fromLP = isLpPool(from);
            bool toLP = isLpPool(to);

            if (toLP && tradeStartBlock == 0) {
                tradeStartBlock = block.number;
            }

            if (fromLP && !toLP && !toExcluded && to != address(swapRouter)) {
                // buy fee
                taxFee = feeConfiguration.buyFees;
                // flag sniper bots when buying in the first 2 blocks
                if (!bot && block.number <= tradeStartBlock + 1) {
                    _setIsBot(to, true);
                    _setIsExcludedFromRewards(to, true);
                    bot = true;
                }
            } else if (toLP && !fromExcluded && !toExcluded) {
                // sell fee
                taxFee = feeConfiguration.sellFees;
            } else if (!fromLP && !toLP && from != address(swapRouter) && !fromExcluded) {
                // transfer fee
                taxFee = feeConfiguration.transferFees;
            }
        }

        // apply max fees to bots
        if (bot) {
            taxFee = MAX_FEE;
        }

        // process fees
        if (processFee && taxFee > 0 && !_lpPools[from]) {
            uint256 contractTokenBalance = balanceOf(address(this));
            if (contractTokenBalance >= numTokensToSwap) {
                _processFees(numTokensToSwap, 0);
            }
        }

        if (taxFee > 0) {
            uint256 taxAmount = (amount * taxFee) / FEE_PRECISION;
            uint256 sendAmount = amount - taxAmount;
            uint256 burnAmount = (taxAmount * feeConfiguration.burnFeeRatio) / FEE_PRECISION;
            uint256 rewardAmount = (taxAmount * feeConfiguration.rewardsFeeRatio) / FEE_PRECISION;

            if (rewardAmount > 0) {
                taxAmount -= rewardAmount;
                sendAmount += rewardAmount;
            }

            if (burnAmount > 0) {
                taxAmount -= burnAmount;
                _executeTokenTransfer(from, BURN_ADDRESS, burnAmount, 0);
            }

            if (taxAmount > 0) {
                _executeTokenTransfer(from, address(this), taxAmount, 0);
            }

            if (sendAmount > 0) {
                _executeTokenTransfer(from, to, sendAmount, rewardAmount);
            }
        } else {
            _executeTokenTransfer(from, to, amount, 0);
        }
    }
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"swapRouter_","type":"address"},{"components":[{"internalType":"uint16","name":"buyFees","type":"uint16"},{"internalType":"uint16","name":"sellFees","type":"uint16"},{"internalType":"uint16","name":"transferFees","type":"uint16"},{"internalType":"uint16","name":"burnFeeRatio","type":"uint16"},{"internalType":"uint16","name":"rewardsFeeRatio","type":"uint16"},{"internalType":"uint16","name":"liquidityFeeRatio","type":"uint16"},{"internalType":"uint16","name":"collectorsFeeRatio","type":"uint16"}],"internalType":"struct TaxToken.FeeConfiguration","name":"feeConfiguration_","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"denied","type":"bool"}],"name":"AddressDenied","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":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"excluded","type":"bool"}],"name":"ExcludedFromAntiWhale","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"excluded","type":"bool"}],"name":"ExcludedFromFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"excluded","type":"bool"}],"name":"ExcludedFromRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeeCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"share","type":"uint256"}],"name":"FeeCollectorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"FeeCollectorRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldShare","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newShare","type":"uint256"}],"name":"FeeCollectorUpdated","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint16","name":"buyFees","type":"uint16"},{"internalType":"uint16","name":"sellFees","type":"uint16"},{"internalType":"uint16","name":"transferFees","type":"uint16"},{"internalType":"uint16","name":"burnFeeRatio","type":"uint16"},{"internalType":"uint16","name":"rewardsFeeRatio","type":"uint16"},{"internalType":"uint16","name":"liquidityFeeRatio","type":"uint16"},{"internalType":"uint16","name":"collectorsFeeRatio","type":"uint16"}],"indexed":false,"internalType":"struct TaxToken.FeeConfiguration","name":"configuration","type":"tuple"}],"name":"FeeConfigurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MaxTokenPerWalletUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isBot","type":"bool"}],"name":"SetIsBot","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pairAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"isLp","type":"bool"}],"name":"SetLpPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"router","type":"address"},{"indexed":true,"internalType":"address","name":"pair","type":"address"}],"name":"SwapRouterUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenRecovered","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferRewards","type":"event"},{"inputs":[],"name":"BURN_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_PRECISION","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"share","type":"uint256"}],"name":"addFeeCollector","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":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"autoProcessFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"distributeFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"feeCollectorShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeConfiguration","outputs":[{"internalType":"uint16","name":"buyFees","type":"uint16"},{"internalType":"uint16","name":"sellFees","type":"uint16"},{"internalType":"uint16","name":"transferFees","type":"uint16"},{"internalType":"uint16","name":"burnFeeRatio","type":"uint16"},{"internalType":"uint16","name":"rewardsFeeRatio","type":"uint16"},{"internalType":"uint16","name":"liquidityFeeRatio","type":"uint16"},{"internalType":"uint16","name":"collectorsFeeRatio","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isAccountDenied","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isBot","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromAntiWhale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromRewards","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isFeeCollector","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pairAddress","type":"address"}],"name":"isLpPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokenPerWallet","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":"numTokensToSwap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"}],"name":"processFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeFeeCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"autoProcess","type":"bool"}],"name":"setAutoprocessFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint16","name":"buyFees","type":"uint16"},{"internalType":"uint16","name":"sellFees","type":"uint16"},{"internalType":"uint16","name":"transferFees","type":"uint16"},{"internalType":"uint16","name":"burnFeeRatio","type":"uint16"},{"internalType":"uint16","name":"rewardsFeeRatio","type":"uint16"},{"internalType":"uint16","name":"liquidityFeeRatio","type":"uint16"},{"internalType":"uint16","name":"collectorsFeeRatio","type":"uint16"}],"internalType":"struct TaxToken.FeeConfiguration","name":"configuration","type":"tuple"}],"name":"setFeeConfiguration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"denied","type":"bool"}],"name":"setIsAccountDenied","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"bot","type":"bool"}],"name":"setIsBot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"excluded","type":"bool"}],"name":"setIsExcludedFromAntiWhale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"excluded","type":"bool"}],"name":"setIsExcludedFromFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"excluded","type":"bool"}],"name":"setIsExcludedFromRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pairAddress","type":"address"},{"internalType":"bool","name":"isLp","type":"bool"}],"name":"setIsLpPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setLiquidityOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMaxTokenPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setNumTokensToSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapRouter","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFeeCollectorsShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRewardFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradeStartBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"share","type":"uint256"}],"name":"updateFeeCollectorShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newRouter","type":"address"}],"name":"updateSwapRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040523480156200001157600080fd5b50604051620047fc380380620047fc833981016040819052620000349162000dfd565b60016127106200004d66470de4df820000600562000eff565b62000059919062000f2f565b838366470de4df8200006200007060648262000f2f565b6040518060400160405280600a815260200169292ca4aa902a37b5b2b760b11b815250604051806040016040528060048152602001635259495560e01b8152506009620000cc620000c66200040d60201b60201c565b62000411565b6006620000da848262000fd5565b506007620000e9838262000fd5565b506008805460ff191660ff929092169190911790555050600a81905562000119620001113390565b600162000461565b6200012630600162000461565b50600c8190556200013a81600019620010a1565b6200014890600019620010b8565b600d819055336000818152600f6020908152604080832094909455600c549351938452919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35060168390556015805460ff60a81b1916600160a81b86151502179055620001bf3390565b601580546001600160a01b039283166001600160a01b0319918216179091556013805492851692909116821790556040805163c45a015560e01b8152905163c45a0155916004808201926020929091908290030181865afa15801562000229573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200024f9190620010ce565b6001600160a01b031663c9c6539630601360009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002b2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002d89190620010ce565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af115801562000326573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200034c9190620010ce565b601480546001600160a01b0319166001600160a01b039290921691821790556000908152601a60205260409020805460ff1916600117905562000398620003903390565b6001620004c1565b620003a5306001620004c1565b620003b0816200057e565b5050601454620003ce92506001600160a01b0316905060016200087f565b620003dd61dead60016200087f565b601454620003f6906001600160a01b0316600162000461565b6200040561dead600162000461565b505062001152565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0382166000818152600b6020908152604091829020805460ff191685151590811790915591519182527f46e542c7dcc512f9d4c5ef6470efcb6729025d935367e1c2c8dc49d8e35eaa8891015b60405180910390a25050565b6001600160a01b03821660009081526019602052604090205481151560ff909116151503620005255760405162461bcd60e51b815260206004820152600b60248201526a105b1c9958591e481cd95d60aa1b60448201526064015b60405180910390fd5b6001600160a01b038216600081815260196020908152604091829020805460ff191685151590811790915591519182527f3499bfcf9673677ba552f3fe2ea274ec7e6246da31c3c87e115b45a9b0db2efb9101620004b5565b80516107d061ffff9091161115620005cb5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206275792066656560881b60448201526064016200051c565b6107d061ffff16816020015161ffff1611156200061e5760405162461bcd60e51b815260206004820152601060248201526f496e76616c69642073656c6c2066656560801b60448201526064016200051c565b6107d061ffff16816040015161ffff1611156200067e5760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964207472616e736665722066656500000000000000000000000060448201526064016200051c565b60008160c001518260a0015183608001518460600151620006a09190620010ec565b620006ac9190620010ec565b620006b89190620010ec565b905061ffff81161580620006d1575061ffff8116612710145b620007135760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642066656520736861726560781b60448201526064016200051c565b81516017805460208501516040808701516060880151608089015160a08a015160c08b015161ffff9081166c010000000000000000000000000261ffff60601b199282166a01000000000000000000000261ffff60501b1994831668010000000000000000029490941663ffffffff60401b1995831666010000000000000261ffff60301b19978416640100000000029790971663ffffffff60201b19998416620100000263ffffffff19909b1693909c16929092179890981796909616989098179290921716929092179190911793909316179055517f670bb2eb703843de33e34597ce04a54a8c44615b8707a7de9214ea24265e3b199062000873908490600060e08201905061ffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401528060a08501511660a08401528060c08501511660c08401525092915050565b60405180910390a15050565b8015156200089d836011620009d960201b620016ef1790919060201c565b151503620008dc5760405162461bcd60e51b815260206004820152600b60248201526a105b1c9958591e481cd95d60aa1b60448201526064016200051c565b801562000962576001600160a01b0382166000908152600f60205260409020541562000940576001600160a01b0382166000908152600f6020526040902054620009269062000a00565b6001600160a01b0383166000908152601060205260409020555b6200095b82601162000a8a60201b620017141790919060201c565b506200099b565b6001600160a01b0382166000908152601060209081526040822091909155620009999060119084906200172962000aa1821b17901c565b505b816001600160a01b03167f6fb704e328736eb59ac6758cc1df5a98a609cfd47a1877201101c614dffc92e982604051620004b5911515815260200190565b6001600160a01b038116600090815260018301602052604081205415155b90505b92915050565b6000600d5482111562000a695760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e74206d757374206265206c657373207468616e20746f74616c207260448201526965666c656374696f6e7360b01b60648201526084016200051c565b600062000a7562000ab8565b905062000a83818462000f2f565b9392505050565b6000620009f7836001600160a01b03841662000ade565b6000620009f7836001600160a01b03841662000b30565b6000808062000ac662000c3b565b909250905062000ad7818362000f2f565b9250505090565b600081815260018301602052604081205462000b2757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620009fa565b506000620009fa565b6000818152600183016020526040812054801562000c2957600062000b57600183620010b8565b855490915060009062000b6d90600190620010b8565b905081811462000bd957600086600001828154811062000b915762000b916200110a565b906000526020600020015490508087600001848154811062000bb75762000bb76200110a565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000bed5762000bed62001120565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620009fa565b6000915050620009fa565b5092915050565b600d54600c546000918291825b62000c5f601162000d7760201b6200173e1760201c565b81101562000d4357600062000c8482601162000d8260201b620017481790919060201c565b6001600160a01b0381166000908152600f602052604090205490915084108062000cc557506001600160a01b03811660009081526010602052604090205483105b1562000cdd57600d54600c5495509550505050509091565b6001600160a01b0381166000908152600f602052604090205462000d029085620010b8565b6001600160a01b03821660009081526010602052604090205490945062000d2a9084620010b8565b925050808062000d3a9062001136565b91505062000c48565b50600c54600d5462000d56919062000f2f565b82101562000d6e57600d54600c549350935050509091565b90939092509050565b6000620009fa825490565b6000620009f78383600082600001828154811062000da45762000da46200110a565b9060005260206000200154905092915050565b80516001600160a01b038116811462000dcf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b805161ffff8116811462000dcf57600080fd5b60008082840361010081121562000e1357600080fd5b62000e1e8462000db7565b925060e0601f198201121562000e3357600080fd5b5060405160e081016001600160401b038111828210171562000e595762000e5962000dd4565b60405262000e6a6020850162000dea565b815262000e7a6040850162000dea565b602082015262000e8d6060850162000dea565b604082015262000ea06080850162000dea565b606082015262000eb360a0850162000dea565b608082015262000ec660c0850162000dea565b60a082015262000ed960e0850162000dea565b60c0820152809150509250929050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417620009fa57620009fa62000ee9565b634e487b7160e01b600052601260045260246000fd5b60008262000f415762000f4162000f19565b500490565b600181811c9082168062000f5b57607f821691505b60208210810362000f7c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000fd057600081815260208120601f850160051c8101602086101562000fab5750805b601f850160051c820191505b8181101562000fcc5782815560010162000fb7565b5050505b505050565b81516001600160401b0381111562000ff15762000ff162000dd4565b620010098162001002845462000f46565b8462000f82565b602080601f831160018114620010415760008415620010285750858301515b600019600386901b1c1916600185901b17855562000fcc565b600085815260208120601f198616915b82811015620010725788860151825594840194600190910190840162001051565b5085821015620010915787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600082620010b357620010b362000f19565b500690565b81810381811115620009fa57620009fa62000ee9565b600060208284031215620010e157600080fd5b620009f78262000db7565b61ffff81811683821601908082111562000c345762000c3462000ee9565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b6000600182016200114b576200114b62000ee9565b5060010190565b61369a80620011626000396000f3fe60806040526004361061031e5760003560e01c806372bc5583116101ab578063b44e9e5c116100f7578063e55096b011610095578063f2fde38b1161006f578063f2fde38b14610a45578063f4232d2514610a65578063f725101d14610a85578063fccc281314610aa557600080fd5b8063e55096b0146109f9578063e63a391f14610a19578063f2c4220e14610a2f57600080fd5b8063bc2fd3bb116100d1578063bc2fd3bb14610979578063bd82394314610999578063c31c9c07146109b9578063dd62ed3e146109d957600080fd5b8063b44e9e5c1461091b578063b98b677f14610930578063bc063e1a1461095057600080fd5b806398c47e8c11610164578063a457c2d71161013e578063a457c2d7146108a5578063a9059cbb146108c5578063adf18693146108e5578063b3c6e9ee1461090557600080fd5b806398c47e8c146107ae5780639b61f1d01461084b5780639edc01ec1461086c57600080fd5b806372bc5583146106ef5780637a8baf521461070f5780637f5bbb2c146107255780638da5cb5b1461074557806394b8a7031461076357806395d89b411461079957600080fd5b8063313ce5671161026a5780633bbac579116102235780636029bf9f116101fd5780636029bf9f146106615780636f741f2a1461068157806370a08231146106ba578063715018a6146106da57600080fd5b80633bbac579146105cf5780634fbee1931461060857806356bcab531461064157600080fd5b8063313ce5671461050d5780633502628a1461052f578063363f1e921461054f5780633935ebf91461056f578063395093511461058f5780633b90b9bf146105af57600080fd5b80630e832273116102d75780631fa67b4d116102b15780631fa67b4d1461045c57806323b872dd1461047c57806326991cc81461049c578063269f534c146104d457600080fd5b80630e832273146104075780630f569dad1461042757806318160ddd1461044757600080fd5b806301a6c43b1461032a57806303c0f5d414610353578063069c9fae1461037557806306fdde0314610395578063095ea7b3146103b75780630a4e42ef146103e757600080fd5b3661032557005b600080fd5b34801561033657600080fd5b5061034060165481565b6040519081526020015b60405180910390f35b34801561035f57600080fd5b5061037361036e366004613178565b610abb565b005b34801561038157600080fd5b506103736103903660046131b1565b610ad1565b3480156103a157600080fd5b506103aa610c21565b60405161034a91906131dd565b3480156103c357600080fd5b506103d76103d23660046131b1565b610cb3565b604051901515815260200161034a565b3480156103f357600080fd5b5061037361040236600461322b565b610ccd565b34801561041357600080fd5b506103d761042236600461324d565b610d29565b34801561043357600080fd5b5061037361044236600461326a565b610d36565b34801561045357600080fd5b50600c54610340565b34801561046857600080fd5b5061037361047736600461324d565b610d43565b34801561048857600080fd5b506103d7610497366004613283565b610d57565b3480156104a857600080fd5b506014546104bc906001600160a01b031681565b6040516001600160a01b03909116815260200161034a565b3480156104e057600080fd5b506103d76104ef36600461324d565b6001600160a01b03166000908152600b602052604090205460ff1690565b34801561051957600080fd5b5060085460405160ff909116815260200161034a565b34801561053b57600080fd5b5061037361054a3660046131b1565b610d7b565b34801561055b57600080fd5b5061037361056a366004613178565b610d8d565b34801561057b57600080fd5b506015546104bc906001600160a01b031681565b34801561059b57600080fd5b506103d76105aa3660046131b1565b610d9f565b3480156105bb57600080fd5b506103d76105ca36600461324d565b610dc1565b3480156105db57600080fd5b506103d76105ea36600461324d565b6001600160a01b03166000908152601b602052604090205460ff1690565b34801561061457600080fd5b506103d761062336600461324d565b6001600160a01b031660009081526019602052604090205460ff1690565b34801561064d57600080fd5b5061037361065c366004613178565b610dce565b34801561066d57600080fd5b5061037361067c36600461326a565b610e20565b34801561068d57600080fd5b506103d761069c36600461324d565b6001600160a01b03166000908152601a602052604090205460ff1690565b3480156106c657600080fd5b506103406106d536600461324d565b610e76565b3480156106e657600080fd5b50610373610ec6565b3480156106fb57600080fd5b5061037361070a36600461324d565b610eda565b34801561071b57600080fd5b50610340600a5481565b34801561073157600080fd5b506103736107403660046132c4565b610f04565b34801561075157600080fd5b506000546001600160a01b03166104bc565b34801561076f57600080fd5b5061034061077e36600461324d565b6001600160a01b031660009081526003602052604090205490565b3480156107a557600080fd5b506103aa610f5a565b3480156107ba57600080fd5b506017546108079061ffff808216916201000081048216916401000000008204811691600160301b8104821691600160401b8204811691600160501b8104821691600160601b9091041687565b6040805161ffff9889168152968816602088015294871694860194909452918516606085015284166080840152831660a083015290911660c082015260e00161034a565b34801561085757600080fd5b506015546103d790600160a81b900460ff1681565b34801561087857600080fd5b506103d761088736600461324d565b6001600160a01b031660009081526009602052604090205460ff1690565b3480156108b157600080fd5b506103d76108c03660046131b1565b610f69565b3480156108d157600080fd5b506103d76108e03660046131b1565b610fe4565b3480156108f157600080fd5b50610373610900366004613178565b610ff2565b34801561091157600080fd5b5061034060045481565b34801561092757600080fd5b50600e54610340565b34801561093c57600080fd5b5061037361094b36600461324d565b611004565b34801561095c57600080fd5b506109666107d081565b60405161ffff909116815260200161034a565b34801561098557600080fd5b506103736109943660046132e1565b611349565b3480156109a557600080fd5b506103736109b436600461326a565b611368565b3480156109c557600080fd5b506013546104bc906001600160a01b031681565b3480156109e557600080fd5b506103406109f43660046132f9565b61141d565b348015610a0557600080fd5b50610373610a14366004613178565b611448565b348015610a2557600080fd5b5061096661271081565b348015610a3b57600080fd5b5061034060185481565b348015610a5157600080fd5b50610373610a6036600461324d565b6114e8565b348015610a7157600080fd5b50610373610a803660046131b1565b61155e565b348015610a9157600080fd5b50610373610aa0366004613178565b61169d565b348015610ab157600080fd5b506104bc61dead81565b610ac3611754565b610acd82826117ae565b5050565b610ad9611754565b60008111610b1f5760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b60448201526064015b60405180910390fd5b6001600160a01b038216610b6057604051339082156108fc029083906000818181858888f19350505050158015610b5a573d6000803e3d6000fd5b50610bda565b60405163a9059cbb60e01b8152336004820152602481018290526001600160a01b0383169063a9059cbb906044016020604051808303816000875af1158015610bad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd19190613327565b610bda57600080fd5b816001600160a01b03167f4590b594be6fdef6bd5e18792a2494ddf2156b618c7bbe48d13a92831208af0582604051610c1591815260200190565b60405180910390a25050565b606060068054610c3090613344565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5c90613344565b8015610ca95780601f10610c7e57610100808354040283529160200191610ca9565b820191906000526020600020905b815481529060010190602001808311610c8c57829003601f168201915b5050505050905090565b600033610cc1818585611846565b60019150505b92915050565b610cd5611754565b610cde30610e76565b821115610d1f5760405162461bcd60e51b815260206004820152600f60248201526e082dadeeadce840e8dede40d0d2ced608b1b6044820152606401610b16565b610acd828261196a565b6000610cc76011836116ef565b610d3e611754565b601655565b610d4b611754565b610d5481611a8e565b50565b600033610d65858285611b5a565b610d70858585611bd4565b506001949350505050565b610d83611754565b610acd8282611ce8565b610d95611754565b610acd8282611df1565b600033610cc1818585610db2838361141d565b610dbc919061338e565b611846565b6000610cc76001836116ef565b610dd6611754565b6001600160a01b03821660009081526009602052604090205481151560ff909116151503610e165760405162461bcd60e51b8152600401610b16906133a1565b610acd8282611ef2565b610e28611754565b47811115610e6d5760405162461bcd60e51b81526020600482015260126024820152714e6f7420656e6f7567682062616c616e636560701b6044820152606401610b16565b610acd81611f4a565b6000610e836011836116ef565b15610ea457506001600160a01b031660009081526010602052604090205490565b6001600160a01b0382166000908152600f6020526040902054610cc790612087565b610ece611754565b610ed86000612104565b565b610ee2611754565b601580546001600160a01b0319166001600160a01b0392909216919091179055565b610f0c611754565b80151560158054906101000a900460ff16151503610f3c5760405162461bcd60e51b8152600401610b16906133a1565b60158054911515600160a81b0260ff60a81b19909216919091179055565b606060078054610c3090613344565b60003381610f77828661141d565b905083811015610fd75760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610b16565b610d708286868403611846565b600033610cc1818585611bd4565b610ffa611754565b610acd8282612154565b61100c611754565b6001600160a01b0381166110535760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b2103937baba32b960911b6044820152606401610b16565b601380546001600160a01b0319166001600160a01b0383169081179091556040805163c45a015560e01b815290516000929163c45a01559160048083019260209291908290030181865afa1580156110af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d391906133c6565b90506001600160a01b03811661111d5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c696420666163746f727960881b6044820152606401610b16565b601354604080516315ab88c960e31b815290516000926001600160a01b03169163ad5c46489160048083019260209291908290030181865afa158015611167573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118b91906133c6565b60405163e6a4390560e01b81523060048201526001600160a01b0380831660248301529192509083169063e6a4390590604401602060405180830381865afa1580156111db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ff91906133c6565b601480546001600160a01b0319166001600160a01b039290921691821790556112b5576040516364e329cb60e11b81523060048201526001600160a01b03828116602483015283169063c9c65396906044016020604051808303816000875af1158015611270573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129491906133c6565b601480546001600160a01b0319166001600160a01b03929092169190911790555b6014546001600160a01b03166113055760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103830b4b91030b2323932b9b99760591b6044820152606401610b16565b6014546013546040516001600160a01b0392831692909116907fca394f95d8dbf1e8b2e76b9a8da90cacce1da85181a65508dab13212dc1df53b90600090a3505050565b611351611754565b610d54611363368390038301836133fa565b6121ec565b611370611754565b600061137b600c5490565b905081600003611389578091505b6103e86113978260056134b8565b6113a191906134cf565b82116113e05760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b6044820152606401610b16565b600a8290556040518281527f0271c3ca991d8fa13fc3df55bfd888e9347a178a375ef6e0f63afa9639d144f4906020015b60405180910390a15050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205490565b611450611754565b6001600160a01b0382166000908152601a602052604090205481151560ff9091161515036114905760405162461bcd60e51b8152600401610b16906133a1565b6001600160a01b0382166000818152601a6020908152604091829020805460ff191685151590811790915591519182527f902b2ea0acdec5a260e398590d055fe29bd61ef5dd41e45db54a4cd98d5569e09101610c15565b6114f0611754565b6001600160a01b0381166115555760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b16565b610d5481612104565b611566611754565b6115716001836116ef565b6115b15760405162461bcd60e51b81526020600482015260116024820152702737ba103332b29031b7b63632b1ba37b960791b6044820152606401610b16565b600081116115f15760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420736861726560981b6044820152606401610b16565b6001600160a01b038216600090815260036020526040812054600480549192839261161d9084906134f1565b90915550506001600160a01b03831660009081526003602052604081208390556004805484929061164f90849061338e565b909155505060408051828152602081018490526001600160a01b038516917fd350c3685bdab1285c0b97ffb6e96d96ed0ad4578a135c38250e771e7cb831aa910160405180910390a2505050565b6116a5611754565b6001600160a01b0382166000908152600b602052604090205481151560ff9091161515036116e55760405162461bcd60e51b8152600401610b16906133a1565b610acd82826124b9565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b600061170d836001600160a01b038416612511565b600061170d836001600160a01b038416612560565b6000610cc7825490565b600061170d838361265a565b6000546001600160a01b03163314610ed85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b16565b6001600160a01b0382166000908152601b602052604090205481151560ff9091161515036117ee5760405162461bcd60e51b8152600401610b16906133a1565b6001600160a01b0382166000818152601b6020908152604091829020805460ff191685151590811790915591519182527f78944a88a78f099ac7c085f813be1e49f300d6d4d637e4dd882ed4ec55639a339101610c15565b6001600160a01b0383166118a85760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610b16565b6001600160a01b0382166119095760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610b16565b6001600160a01b0383811660008181526005602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6015805460ff60a01b1916600160a01b179055600061198830610e76565b9050828110611a7c5760175460009061ffff600160401b82048116916119b991600160301b90910416612710613504565b6119c39190613504565b60175461ffff918216916119df91600160501b900416866134b8565b6119e991906134cf565b905060006119f86002836134cf565b90506000611a0683876134f1565b9050600081611a1584866134f1565b611a1f919061338e565b90508015611a6d5747611a328288612684565b6000611a3e82476134f1565b9050600083611a4d87846134b8565b611a5791906134cf565b90508015611a6957611a6986826127de565b5050505b611a7647611f4a565b50505050505b50506015805460ff60a01b1916905550565b611a996001826116ef565b611ad95760405162461bcd60e51b81526020600482015260116024820152702737ba103332b29031b7b63632b1ba37b960791b6044820152606401610b16565b611ae4600182611729565b506001600160a01b0381166000908152600360205260408120546004805491929091611b119084906134f1565b90915550506001600160a01b038116600081815260036020526040808220829055517f904316769e154356a5e4aad5d41591b55913c7717fab281d818c1fed7d80e8149190a250565b6000611b66848461141d565b90506000198114611bce5781811015611bc15760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610b16565b611bce8484848403611846565b50505050565b6001600160a01b038316611c385760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610b16565b6001600160a01b038216611c9a5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610b16565b611ca5838383612892565b6000611cb084610e76565b905081811015611cd25760405162461bcd60e51b8152600401610b169061351f565b611cdd8484846128a2565b611bce848484612c38565b611cf36001836116ef565b15611d385760405162461bcd60e51b815260206004820152601560248201527420b63932b0b23c903332b29031b7b63632b1ba37b960591b6044820152606401610b16565b60008111611d785760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420736861726560981b6044820152606401610b16565b611d83600183611714565b506001600160a01b038216600090815260036020526040812082905560048054839290611db190849061338e565b90915550506040518181526001600160a01b038316907f918584c21fe4a093f5014c0dabaed3e43b642781e27984aef122cae8245fbb2390602001610c15565b801515611dff6011846116ef565b151503611e1e5760405162461bcd60e51b8152600401610b16906133a1565b8015611e8f576001600160a01b0382166000908152600f602052604090205415611e7e576001600160a01b0382166000908152600f6020526040902054611e6490612087565b6001600160a01b0383166000908152601060205260409020555b611e89601183611714565b50611eb5565b6001600160a01b038216600090815260106020526040812055611eb3601183611729565b505b816001600160a01b03167f6fb704e328736eb59ac6758cc1df5a98a609cfd47a1877201101c614dffc92e982604051610c15911515815260200190565b6001600160a01b038216600081815260096020908152604091829020805460ff191685151590811790915591519182527f7a13f05e990e10c4305194192f2e26b183fa8e7e24e46ec432784d8dbe004d3d9101610c15565b600081600003611f5c57506000919050565b600454600003611f6e57506000919050565b600080611f7b600161173e565b905060005b81811015610d70576000611f95600183611748565b90506000611fa46001856134f1565b8314611fdf576004546001600160a01b038316600090815260036020526040902054611fd090896134b8565b611fda91906134cf565b611fe9565b611fe985886134f1565b6040519091506001600160a01b0383169082156108fc029083906000818181858888f19350505050158015612022573d6000803e3d6000fd5b50816001600160a01b03167f06c5efeff5c320943d265dc4e5f1af95ad523555ce0c1957e367dda5514572df8260405161205e91815260200190565b60405180910390a2612070818661338e565b94505050808061207f90613565565b915050611f80565b6000600d548211156120ee5760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e74206d757374206265206c657373207468616e20746f74616c207260448201526965666c656374696f6e7360b01b6064820152608401610b16565b60006120f8612c43565b905061170d81846134cf565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03821660009081526019602052604090205481151560ff9091161515036121945760405162461bcd60e51b8152600401610b16906133a1565b6001600160a01b038216600081815260196020908152604091829020805460ff191685151590811790915591519182527f3499bfcf9673677ba552f3fe2ea274ec7e6246da31c3c87e115b45a9b0db2efb9101610c15565b80516107d061ffff90911611156122375760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206275792066656560881b6044820152606401610b16565b6107d061ffff16816020015161ffff1611156122885760405162461bcd60e51b815260206004820152601060248201526f496e76616c69642073656c6c2066656560801b6044820152606401610b16565b6107d061ffff16816040015161ffff1611156122dd5760405162461bcd60e51b8152602060048201526014602482015273496e76616c6964207472616e736665722066656560601b6044820152606401610b16565b60008160c001518260a00151836080015184606001516122fd919061357e565b612307919061357e565b612311919061357e565b905061ffff81161580612329575061ffff8116612710145b6123695760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642066656520736861726560781b6044820152606401610b16565b81516017805460208501516040808701516060880151608089015160a08a015160c08b015161ffff908116600160601b0261ffff60601b19928216600160501b0261ffff60501b19948316600160401b02949094166bffffffff000000000000000019958316600160301b0267ffff00000000000019978416640100000000029790971667ffffffff0000000019998416620100000263ffffffff19909b1693909c16929092179890981796909616989098179290921716929092179190911793909316179055517f670bb2eb703843de33e34597ce04a54a8c44615b8707a7de9214ea24265e3b1990611411908490600060e08201905061ffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401528060a08501511660a08401528060c08501511660c08401525092915050565b6001600160a01b0382166000818152600b6020908152604091829020805460ff191685151590811790915591519182527f46e542c7dcc512f9d4c5ef6470efcb6729025d935367e1c2c8dc49d8e35eaa889101610c15565b600081815260018301602052604081205461255857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610cc7565b506000610cc7565b600081815260018301602052604081205480156126495760006125846001836134f1565b8554909150600090612598906001906134f1565b90508181146125fd5760008660000182815481106125b8576125b8613599565b90600052602060002001549050808760000184815481106125db576125db613599565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061260e5761260e6135af565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610cc7565b6000915050610cc7565b5092915050565b600082600001828154811061267157612671613599565b9060005260206000200154905092915050565b60408051600280825260608201835260009260208301908036833701905050905030816000815181106126b9576126b9613599565b6001600160a01b03928316602091820292909201810191909152601354604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015612712573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061273691906133c6565b8160018151811061274957612749613599565b6001600160a01b03928316602091820292909201015260135461276f9130911685611846565b60135460405163791ac94760e01b81526001600160a01b039091169063791ac947906127a790869086908690309042906004016135c5565b600060405180830381600087803b1580156127c157600080fd5b505af11580156127d5573d6000803e3d6000fd5b50505050505050565b6013546127f69030906001600160a01b031684611846565b60135460155460405163f305d71960e01b81523060048201526024810185905260006044820181905260648201526001600160a01b0391821660848201524260a482015291169063f305d71990839060c40160606040518083038185885af1158015612866573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061288b9190613636565b5050505050565b61289d838383612c66565b505050565b600081116128e25760405162461bcd60e51b815260206004820152600d60248201526c05472616e73666572203c3d203609c1b6044820152606401610b16565b6015546000908190600160a01b900460ff1615801561290a5750601554600160a81b900460ff165b801561291857506000601854115b6001600160a01b0386166000908152601b60205260408120549192509060ff168061295b57506001600160a01b0385166000908152601b602052604090205460ff165b601554909150600160a01b900460ff16612ac6576001600160a01b03868116600081815260196020908152604080832054948a1680845281842054948452601a909252808320549183529091205460ff938416939283169291821691168080156129c55750601854155b156129cf57436018555b8180156129da575080155b80156129e4575082155b80156129fe57506013546001600160a01b038a8116911614155b15612a4c5760175461ffff16965084158015612a275750601854612a2390600161338e565b4311155b15612a4757612a378960016117ae565b612a42896001611df1565b600194505b612ac1565b808015612a57575083155b8015612a61575082155b15612a7a5760175462010000900461ffff169650612ac1565b81158015612a86575080155b8015612aa057506013546001600160a01b038b8116911614155b8015612aaa575083155b15612ac157601754640100000000900461ffff1696505b505050505b8015612ad2576107d092505b818015612adf5750600083115b8015612b0457506001600160a01b0386166000908152601a602052604090205460ff16155b15612b2e576000612b1430610e76565b90506016548110612b2c57612b2c601654600061196a565b505b8215612c23576000612710612b4385876134b8565b612b4d91906134cf565b90506000612b5b82876134f1565b60175490915060009061271090612b7d90600160301b900461ffff16856134b8565b612b8791906134cf565b60175490915060009061271090612ba990600160401b900461ffff16866134b8565b612bb391906134cf565b90508015612bd457612bc581856134f1565b9350612bd1818461338e565b92505b8115612bf557612be482856134f1565b9350612bf58a61dead846000612d23565b8315612c0857612c088a30866000612d23565b8215612c1a57612c1a8a8a8584612d23565b50505050612c30565b612c308686866000612d23565b505050505050565b61289d838383612f35565b6000806000612c50612faf565b9092509050612c5f81836134cf565b9250505090565b6001600160a01b038316600090815260096020526040902054839060ff1615612cc25760405162461bcd60e51b815260206004820152600e60248201526d1059191c995cdcc819195b9a595960921b6044820152606401610b16565b6001600160a01b038316600090815260096020526040902054839060ff1615612d1e5760405162461bcd60e51b815260206004820152600e60248201526d1059191c995cdcc819195b9a595960921b6044820152606401610b16565b61288b565b6000806000806000612d3587876130c1565b6001600160a01b038e166000908152600f602052604090205494995092975090955093509150851115612d7a5760405162461bcd60e51b8152600401610b169061351f565b6001600160a01b0389166000908152600f602052604081208054879290612da29084906134f1565b90915550506001600160a01b0388166000908152600f602052604081208054869290612dcf90849061338e565b90915550612de0905060118a6116ef565b15612e4b576001600160a01b038916600090815260106020526040902054871115612e1d5760405162461bcd60e51b8152600401610b169061351f565b6001600160a01b03891660009081526010602052604081208054899290612e459084906134f1565b90915550505b612e566011896116ef565b15612e89576001600160a01b03881660009081526010602052604081208054849290612e8390849061338e565b90915550505b612e938382613121565b876001600160a01b0316896001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612ed891815260200190565b60405180910390a38515612f2a57886001600160a01b03167f9ffbf50289a7a68340713701e9c2c0b22a6edc0b16140bf4d3ced3fcd0ba128387604051612f2191815260200190565b60405180910390a25b505050505050505050565b6001600160a01b0382166000908152600b602052604090205460ff1661289d57600a54612f6183610e76565b111561289d5760405162461bcd60e51b815260206004820152601b60248201527f416e74695768616c653a2062616c616e636520746f6f206869676800000000006044820152606401610b16565b600d54600c546000918291825b612fc6601161173e565b811015613090576000612fda601183611748565b6001600160a01b0381166000908152600f602052604090205490915084108061301a57506001600160a01b03811660009081526010602052604090205483105b1561303157600d54600c5495509550505050509091565b6001600160a01b0381166000908152600f602052604090205461305490856134f1565b6001600160a01b03821660009081526010602052604090205490945061307a90846134f1565b925050808061308890613565565b915050612fbc565b50600c54600d546130a191906134cf565b8210156130b857600d54600c549350935050509091565b90939092509050565b6000806000806000806130d2612c43565b905060006130e0828a6134b8565b905060006130ee838a6134b8565b905060006130fc82846134f1565b905082818361310b8d8f6134f1565b929e919d509b919a509098509650505050505050565b81600d600082825461313391906134f1565b9250508190555080600e600082825461314c919061338e565b90915550505050565b6001600160a01b0381168114610d5457600080fd5b8015158114610d5457600080fd5b6000806040838503121561318b57600080fd5b823561319681613155565b915060208301356131a68161316a565b809150509250929050565b600080604083850312156131c457600080fd5b82356131cf81613155565b946020939093013593505050565b600060208083528351808285015260005b8181101561320a578581018301518582016040015282016131ee565b506000604082860101526040601f19601f8301168501019250505092915050565b6000806040838503121561323e57600080fd5b50508035926020909101359150565b60006020828403121561325f57600080fd5b813561170d81613155565b60006020828403121561327c57600080fd5b5035919050565b60008060006060848603121561329857600080fd5b83356132a381613155565b925060208401356132b381613155565b929592945050506040919091013590565b6000602082840312156132d657600080fd5b813561170d8161316a565b600060e082840312156132f357600080fd5b50919050565b6000806040838503121561330c57600080fd5b823561331781613155565b915060208301356131a681613155565b60006020828403121561333957600080fd5b815161170d8161316a565b600181811c9082168061335857607f821691505b6020821081036132f357634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115610cc757610cc7613378565b6020808252600b908201526a105b1c9958591e481cd95d60aa1b604082015260600190565b6000602082840312156133d857600080fd5b815161170d81613155565b803561ffff811681146133f557600080fd5b919050565b600060e0828403121561340c57600080fd5b60405160e0810181811067ffffffffffffffff8211171561343d57634e487b7160e01b600052604160045260246000fd5b604052613449836133e3565b8152613457602084016133e3565b6020820152613468604084016133e3565b6040820152613479606084016133e3565b606082015261348a608084016133e3565b608082015261349b60a084016133e3565b60a08201526134ac60c084016133e3565b60c08201529392505050565b8082028115828204841417610cc757610cc7613378565b6000826134ec57634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610cc757610cc7613378565b61ffff82811682821603908082111561265357612653613378565b60208082526026908201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604082015265616c616e636560d01b606082015260800190565b60006001820161357757613577613378565b5060010190565b61ffff81811683821601908082111561265357612653613378565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156136155784516001600160a01b0316835293830193918301916001016135f0565b50506001600160a01b03969096166060850152505050608001529392505050565b60008060006060848603121561364b57600080fd5b835192506020840151915060408401519050925092509256fea264697066735822122070c85e3921b15b4138ccb2a0aa825d6de4280731c47c36f695e274674a0ee16d64736f6c634300081100330000000000000000000000004752ba5dbc23f44d87826276bf6fd6b1c372ad24000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009c4000000000000000000000000000000000000000000000000000000000000138800000000000000000000000000000000000000000000000000000000000009c40000000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x60806040526004361061031e5760003560e01c806372bc5583116101ab578063b44e9e5c116100f7578063e55096b011610095578063f2fde38b1161006f578063f2fde38b14610a45578063f4232d2514610a65578063f725101d14610a85578063fccc281314610aa557600080fd5b8063e55096b0146109f9578063e63a391f14610a19578063f2c4220e14610a2f57600080fd5b8063bc2fd3bb116100d1578063bc2fd3bb14610979578063bd82394314610999578063c31c9c07146109b9578063dd62ed3e146109d957600080fd5b8063b44e9e5c1461091b578063b98b677f14610930578063bc063e1a1461095057600080fd5b806398c47e8c11610164578063a457c2d71161013e578063a457c2d7146108a5578063a9059cbb146108c5578063adf18693146108e5578063b3c6e9ee1461090557600080fd5b806398c47e8c146107ae5780639b61f1d01461084b5780639edc01ec1461086c57600080fd5b806372bc5583146106ef5780637a8baf521461070f5780637f5bbb2c146107255780638da5cb5b1461074557806394b8a7031461076357806395d89b411461079957600080fd5b8063313ce5671161026a5780633bbac579116102235780636029bf9f116101fd5780636029bf9f146106615780636f741f2a1461068157806370a08231146106ba578063715018a6146106da57600080fd5b80633bbac579146105cf5780634fbee1931461060857806356bcab531461064157600080fd5b8063313ce5671461050d5780633502628a1461052f578063363f1e921461054f5780633935ebf91461056f578063395093511461058f5780633b90b9bf146105af57600080fd5b80630e832273116102d75780631fa67b4d116102b15780631fa67b4d1461045c57806323b872dd1461047c57806326991cc81461049c578063269f534c146104d457600080fd5b80630e832273146104075780630f569dad1461042757806318160ddd1461044757600080fd5b806301a6c43b1461032a57806303c0f5d414610353578063069c9fae1461037557806306fdde0314610395578063095ea7b3146103b75780630a4e42ef146103e757600080fd5b3661032557005b600080fd5b34801561033657600080fd5b5061034060165481565b6040519081526020015b60405180910390f35b34801561035f57600080fd5b5061037361036e366004613178565b610abb565b005b34801561038157600080fd5b506103736103903660046131b1565b610ad1565b3480156103a157600080fd5b506103aa610c21565b60405161034a91906131dd565b3480156103c357600080fd5b506103d76103d23660046131b1565b610cb3565b604051901515815260200161034a565b3480156103f357600080fd5b5061037361040236600461322b565b610ccd565b34801561041357600080fd5b506103d761042236600461324d565b610d29565b34801561043357600080fd5b5061037361044236600461326a565b610d36565b34801561045357600080fd5b50600c54610340565b34801561046857600080fd5b5061037361047736600461324d565b610d43565b34801561048857600080fd5b506103d7610497366004613283565b610d57565b3480156104a857600080fd5b506014546104bc906001600160a01b031681565b6040516001600160a01b03909116815260200161034a565b3480156104e057600080fd5b506103d76104ef36600461324d565b6001600160a01b03166000908152600b602052604090205460ff1690565b34801561051957600080fd5b5060085460405160ff909116815260200161034a565b34801561053b57600080fd5b5061037361054a3660046131b1565b610d7b565b34801561055b57600080fd5b5061037361056a366004613178565b610d8d565b34801561057b57600080fd5b506015546104bc906001600160a01b031681565b34801561059b57600080fd5b506103d76105aa3660046131b1565b610d9f565b3480156105bb57600080fd5b506103d76105ca36600461324d565b610dc1565b3480156105db57600080fd5b506103d76105ea36600461324d565b6001600160a01b03166000908152601b602052604090205460ff1690565b34801561061457600080fd5b506103d761062336600461324d565b6001600160a01b031660009081526019602052604090205460ff1690565b34801561064d57600080fd5b5061037361065c366004613178565b610dce565b34801561066d57600080fd5b5061037361067c36600461326a565b610e20565b34801561068d57600080fd5b506103d761069c36600461324d565b6001600160a01b03166000908152601a602052604090205460ff1690565b3480156106c657600080fd5b506103406106d536600461324d565b610e76565b3480156106e657600080fd5b50610373610ec6565b3480156106fb57600080fd5b5061037361070a36600461324d565b610eda565b34801561071b57600080fd5b50610340600a5481565b34801561073157600080fd5b506103736107403660046132c4565b610f04565b34801561075157600080fd5b506000546001600160a01b03166104bc565b34801561076f57600080fd5b5061034061077e36600461324d565b6001600160a01b031660009081526003602052604090205490565b3480156107a557600080fd5b506103aa610f5a565b3480156107ba57600080fd5b506017546108079061ffff808216916201000081048216916401000000008204811691600160301b8104821691600160401b8204811691600160501b8104821691600160601b9091041687565b6040805161ffff9889168152968816602088015294871694860194909452918516606085015284166080840152831660a083015290911660c082015260e00161034a565b34801561085757600080fd5b506015546103d790600160a81b900460ff1681565b34801561087857600080fd5b506103d761088736600461324d565b6001600160a01b031660009081526009602052604090205460ff1690565b3480156108b157600080fd5b506103d76108c03660046131b1565b610f69565b3480156108d157600080fd5b506103d76108e03660046131b1565b610fe4565b3480156108f157600080fd5b50610373610900366004613178565b610ff2565b34801561091157600080fd5b5061034060045481565b34801561092757600080fd5b50600e54610340565b34801561093c57600080fd5b5061037361094b36600461324d565b611004565b34801561095c57600080fd5b506109666107d081565b60405161ffff909116815260200161034a565b34801561098557600080fd5b506103736109943660046132e1565b611349565b3480156109a557600080fd5b506103736109b436600461326a565b611368565b3480156109c557600080fd5b506013546104bc906001600160a01b031681565b3480156109e557600080fd5b506103406109f43660046132f9565b61141d565b348015610a0557600080fd5b50610373610a14366004613178565b611448565b348015610a2557600080fd5b5061096661271081565b348015610a3b57600080fd5b5061034060185481565b348015610a5157600080fd5b50610373610a6036600461324d565b6114e8565b348015610a7157600080fd5b50610373610a803660046131b1565b61155e565b348015610a9157600080fd5b50610373610aa0366004613178565b61169d565b348015610ab157600080fd5b506104bc61dead81565b610ac3611754565b610acd82826117ae565b5050565b610ad9611754565b60008111610b1f5760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b60448201526064015b60405180910390fd5b6001600160a01b038216610b6057604051339082156108fc029083906000818181858888f19350505050158015610b5a573d6000803e3d6000fd5b50610bda565b60405163a9059cbb60e01b8152336004820152602481018290526001600160a01b0383169063a9059cbb906044016020604051808303816000875af1158015610bad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd19190613327565b610bda57600080fd5b816001600160a01b03167f4590b594be6fdef6bd5e18792a2494ddf2156b618c7bbe48d13a92831208af0582604051610c1591815260200190565b60405180910390a25050565b606060068054610c3090613344565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5c90613344565b8015610ca95780601f10610c7e57610100808354040283529160200191610ca9565b820191906000526020600020905b815481529060010190602001808311610c8c57829003601f168201915b5050505050905090565b600033610cc1818585611846565b60019150505b92915050565b610cd5611754565b610cde30610e76565b821115610d1f5760405162461bcd60e51b815260206004820152600f60248201526e082dadeeadce840e8dede40d0d2ced608b1b6044820152606401610b16565b610acd828261196a565b6000610cc76011836116ef565b610d3e611754565b601655565b610d4b611754565b610d5481611a8e565b50565b600033610d65858285611b5a565b610d70858585611bd4565b506001949350505050565b610d83611754565b610acd8282611ce8565b610d95611754565b610acd8282611df1565b600033610cc1818585610db2838361141d565b610dbc919061338e565b611846565b6000610cc76001836116ef565b610dd6611754565b6001600160a01b03821660009081526009602052604090205481151560ff909116151503610e165760405162461bcd60e51b8152600401610b16906133a1565b610acd8282611ef2565b610e28611754565b47811115610e6d5760405162461bcd60e51b81526020600482015260126024820152714e6f7420656e6f7567682062616c616e636560701b6044820152606401610b16565b610acd81611f4a565b6000610e836011836116ef565b15610ea457506001600160a01b031660009081526010602052604090205490565b6001600160a01b0382166000908152600f6020526040902054610cc790612087565b610ece611754565b610ed86000612104565b565b610ee2611754565b601580546001600160a01b0319166001600160a01b0392909216919091179055565b610f0c611754565b80151560158054906101000a900460ff16151503610f3c5760405162461bcd60e51b8152600401610b16906133a1565b60158054911515600160a81b0260ff60a81b19909216919091179055565b606060078054610c3090613344565b60003381610f77828661141d565b905083811015610fd75760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610b16565b610d708286868403611846565b600033610cc1818585611bd4565b610ffa611754565b610acd8282612154565b61100c611754565b6001600160a01b0381166110535760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b2103937baba32b960911b6044820152606401610b16565b601380546001600160a01b0319166001600160a01b0383169081179091556040805163c45a015560e01b815290516000929163c45a01559160048083019260209291908290030181865afa1580156110af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d391906133c6565b90506001600160a01b03811661111d5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c696420666163746f727960881b6044820152606401610b16565b601354604080516315ab88c960e31b815290516000926001600160a01b03169163ad5c46489160048083019260209291908290030181865afa158015611167573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118b91906133c6565b60405163e6a4390560e01b81523060048201526001600160a01b0380831660248301529192509083169063e6a4390590604401602060405180830381865afa1580156111db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ff91906133c6565b601480546001600160a01b0319166001600160a01b039290921691821790556112b5576040516364e329cb60e11b81523060048201526001600160a01b03828116602483015283169063c9c65396906044016020604051808303816000875af1158015611270573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129491906133c6565b601480546001600160a01b0319166001600160a01b03929092169190911790555b6014546001600160a01b03166113055760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103830b4b91030b2323932b9b99760591b6044820152606401610b16565b6014546013546040516001600160a01b0392831692909116907fca394f95d8dbf1e8b2e76b9a8da90cacce1da85181a65508dab13212dc1df53b90600090a3505050565b611351611754565b610d54611363368390038301836133fa565b6121ec565b611370611754565b600061137b600c5490565b905081600003611389578091505b6103e86113978260056134b8565b6113a191906134cf565b82116113e05760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b6044820152606401610b16565b600a8290556040518281527f0271c3ca991d8fa13fc3df55bfd888e9347a178a375ef6e0f63afa9639d144f4906020015b60405180910390a15050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205490565b611450611754565b6001600160a01b0382166000908152601a602052604090205481151560ff9091161515036114905760405162461bcd60e51b8152600401610b16906133a1565b6001600160a01b0382166000818152601a6020908152604091829020805460ff191685151590811790915591519182527f902b2ea0acdec5a260e398590d055fe29bd61ef5dd41e45db54a4cd98d5569e09101610c15565b6114f0611754565b6001600160a01b0381166115555760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b16565b610d5481612104565b611566611754565b6115716001836116ef565b6115b15760405162461bcd60e51b81526020600482015260116024820152702737ba103332b29031b7b63632b1ba37b960791b6044820152606401610b16565b600081116115f15760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420736861726560981b6044820152606401610b16565b6001600160a01b038216600090815260036020526040812054600480549192839261161d9084906134f1565b90915550506001600160a01b03831660009081526003602052604081208390556004805484929061164f90849061338e565b909155505060408051828152602081018490526001600160a01b038516917fd350c3685bdab1285c0b97ffb6e96d96ed0ad4578a135c38250e771e7cb831aa910160405180910390a2505050565b6116a5611754565b6001600160a01b0382166000908152600b602052604090205481151560ff9091161515036116e55760405162461bcd60e51b8152600401610b16906133a1565b610acd82826124b9565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b600061170d836001600160a01b038416612511565b600061170d836001600160a01b038416612560565b6000610cc7825490565b600061170d838361265a565b6000546001600160a01b03163314610ed85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b16565b6001600160a01b0382166000908152601b602052604090205481151560ff9091161515036117ee5760405162461bcd60e51b8152600401610b16906133a1565b6001600160a01b0382166000818152601b6020908152604091829020805460ff191685151590811790915591519182527f78944a88a78f099ac7c085f813be1e49f300d6d4d637e4dd882ed4ec55639a339101610c15565b6001600160a01b0383166118a85760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610b16565b6001600160a01b0382166119095760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610b16565b6001600160a01b0383811660008181526005602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6015805460ff60a01b1916600160a01b179055600061198830610e76565b9050828110611a7c5760175460009061ffff600160401b82048116916119b991600160301b90910416612710613504565b6119c39190613504565b60175461ffff918216916119df91600160501b900416866134b8565b6119e991906134cf565b905060006119f86002836134cf565b90506000611a0683876134f1565b9050600081611a1584866134f1565b611a1f919061338e565b90508015611a6d5747611a328288612684565b6000611a3e82476134f1565b9050600083611a4d87846134b8565b611a5791906134cf565b90508015611a6957611a6986826127de565b5050505b611a7647611f4a565b50505050505b50506015805460ff60a01b1916905550565b611a996001826116ef565b611ad95760405162461bcd60e51b81526020600482015260116024820152702737ba103332b29031b7b63632b1ba37b960791b6044820152606401610b16565b611ae4600182611729565b506001600160a01b0381166000908152600360205260408120546004805491929091611b119084906134f1565b90915550506001600160a01b038116600081815260036020526040808220829055517f904316769e154356a5e4aad5d41591b55913c7717fab281d818c1fed7d80e8149190a250565b6000611b66848461141d565b90506000198114611bce5781811015611bc15760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610b16565b611bce8484848403611846565b50505050565b6001600160a01b038316611c385760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610b16565b6001600160a01b038216611c9a5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610b16565b611ca5838383612892565b6000611cb084610e76565b905081811015611cd25760405162461bcd60e51b8152600401610b169061351f565b611cdd8484846128a2565b611bce848484612c38565b611cf36001836116ef565b15611d385760405162461bcd60e51b815260206004820152601560248201527420b63932b0b23c903332b29031b7b63632b1ba37b960591b6044820152606401610b16565b60008111611d785760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420736861726560981b6044820152606401610b16565b611d83600183611714565b506001600160a01b038216600090815260036020526040812082905560048054839290611db190849061338e565b90915550506040518181526001600160a01b038316907f918584c21fe4a093f5014c0dabaed3e43b642781e27984aef122cae8245fbb2390602001610c15565b801515611dff6011846116ef565b151503611e1e5760405162461bcd60e51b8152600401610b16906133a1565b8015611e8f576001600160a01b0382166000908152600f602052604090205415611e7e576001600160a01b0382166000908152600f6020526040902054611e6490612087565b6001600160a01b0383166000908152601060205260409020555b611e89601183611714565b50611eb5565b6001600160a01b038216600090815260106020526040812055611eb3601183611729565b505b816001600160a01b03167f6fb704e328736eb59ac6758cc1df5a98a609cfd47a1877201101c614dffc92e982604051610c15911515815260200190565b6001600160a01b038216600081815260096020908152604091829020805460ff191685151590811790915591519182527f7a13f05e990e10c4305194192f2e26b183fa8e7e24e46ec432784d8dbe004d3d9101610c15565b600081600003611f5c57506000919050565b600454600003611f6e57506000919050565b600080611f7b600161173e565b905060005b81811015610d70576000611f95600183611748565b90506000611fa46001856134f1565b8314611fdf576004546001600160a01b038316600090815260036020526040902054611fd090896134b8565b611fda91906134cf565b611fe9565b611fe985886134f1565b6040519091506001600160a01b0383169082156108fc029083906000818181858888f19350505050158015612022573d6000803e3d6000fd5b50816001600160a01b03167f06c5efeff5c320943d265dc4e5f1af95ad523555ce0c1957e367dda5514572df8260405161205e91815260200190565b60405180910390a2612070818661338e565b94505050808061207f90613565565b915050611f80565b6000600d548211156120ee5760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e74206d757374206265206c657373207468616e20746f74616c207260448201526965666c656374696f6e7360b01b6064820152608401610b16565b60006120f8612c43565b905061170d81846134cf565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03821660009081526019602052604090205481151560ff9091161515036121945760405162461bcd60e51b8152600401610b16906133a1565b6001600160a01b038216600081815260196020908152604091829020805460ff191685151590811790915591519182527f3499bfcf9673677ba552f3fe2ea274ec7e6246da31c3c87e115b45a9b0db2efb9101610c15565b80516107d061ffff90911611156122375760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206275792066656560881b6044820152606401610b16565b6107d061ffff16816020015161ffff1611156122885760405162461bcd60e51b815260206004820152601060248201526f496e76616c69642073656c6c2066656560801b6044820152606401610b16565b6107d061ffff16816040015161ffff1611156122dd5760405162461bcd60e51b8152602060048201526014602482015273496e76616c6964207472616e736665722066656560601b6044820152606401610b16565b60008160c001518260a00151836080015184606001516122fd919061357e565b612307919061357e565b612311919061357e565b905061ffff81161580612329575061ffff8116612710145b6123695760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642066656520736861726560781b6044820152606401610b16565b81516017805460208501516040808701516060880151608089015160a08a015160c08b015161ffff908116600160601b0261ffff60601b19928216600160501b0261ffff60501b19948316600160401b02949094166bffffffff000000000000000019958316600160301b0267ffff00000000000019978416640100000000029790971667ffffffff0000000019998416620100000263ffffffff19909b1693909c16929092179890981796909616989098179290921716929092179190911793909316179055517f670bb2eb703843de33e34597ce04a54a8c44615b8707a7de9214ea24265e3b1990611411908490600060e08201905061ffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401528060a08501511660a08401528060c08501511660c08401525092915050565b6001600160a01b0382166000818152600b6020908152604091829020805460ff191685151590811790915591519182527f46e542c7dcc512f9d4c5ef6470efcb6729025d935367e1c2c8dc49d8e35eaa889101610c15565b600081815260018301602052604081205461255857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610cc7565b506000610cc7565b600081815260018301602052604081205480156126495760006125846001836134f1565b8554909150600090612598906001906134f1565b90508181146125fd5760008660000182815481106125b8576125b8613599565b90600052602060002001549050808760000184815481106125db576125db613599565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061260e5761260e6135af565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610cc7565b6000915050610cc7565b5092915050565b600082600001828154811061267157612671613599565b9060005260206000200154905092915050565b60408051600280825260608201835260009260208301908036833701905050905030816000815181106126b9576126b9613599565b6001600160a01b03928316602091820292909201810191909152601354604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015612712573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061273691906133c6565b8160018151811061274957612749613599565b6001600160a01b03928316602091820292909201015260135461276f9130911685611846565b60135460405163791ac94760e01b81526001600160a01b039091169063791ac947906127a790869086908690309042906004016135c5565b600060405180830381600087803b1580156127c157600080fd5b505af11580156127d5573d6000803e3d6000fd5b50505050505050565b6013546127f69030906001600160a01b031684611846565b60135460155460405163f305d71960e01b81523060048201526024810185905260006044820181905260648201526001600160a01b0391821660848201524260a482015291169063f305d71990839060c40160606040518083038185885af1158015612866573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061288b9190613636565b5050505050565b61289d838383612c66565b505050565b600081116128e25760405162461bcd60e51b815260206004820152600d60248201526c05472616e73666572203c3d203609c1b6044820152606401610b16565b6015546000908190600160a01b900460ff1615801561290a5750601554600160a81b900460ff165b801561291857506000601854115b6001600160a01b0386166000908152601b60205260408120549192509060ff168061295b57506001600160a01b0385166000908152601b602052604090205460ff165b601554909150600160a01b900460ff16612ac6576001600160a01b03868116600081815260196020908152604080832054948a1680845281842054948452601a909252808320549183529091205460ff938416939283169291821691168080156129c55750601854155b156129cf57436018555b8180156129da575080155b80156129e4575082155b80156129fe57506013546001600160a01b038a8116911614155b15612a4c5760175461ffff16965084158015612a275750601854612a2390600161338e565b4311155b15612a4757612a378960016117ae565b612a42896001611df1565b600194505b612ac1565b808015612a57575083155b8015612a61575082155b15612a7a5760175462010000900461ffff169650612ac1565b81158015612a86575080155b8015612aa057506013546001600160a01b038b8116911614155b8015612aaa575083155b15612ac157601754640100000000900461ffff1696505b505050505b8015612ad2576107d092505b818015612adf5750600083115b8015612b0457506001600160a01b0386166000908152601a602052604090205460ff16155b15612b2e576000612b1430610e76565b90506016548110612b2c57612b2c601654600061196a565b505b8215612c23576000612710612b4385876134b8565b612b4d91906134cf565b90506000612b5b82876134f1565b60175490915060009061271090612b7d90600160301b900461ffff16856134b8565b612b8791906134cf565b60175490915060009061271090612ba990600160401b900461ffff16866134b8565b612bb391906134cf565b90508015612bd457612bc581856134f1565b9350612bd1818461338e565b92505b8115612bf557612be482856134f1565b9350612bf58a61dead846000612d23565b8315612c0857612c088a30866000612d23565b8215612c1a57612c1a8a8a8584612d23565b50505050612c30565b612c308686866000612d23565b505050505050565b61289d838383612f35565b6000806000612c50612faf565b9092509050612c5f81836134cf565b9250505090565b6001600160a01b038316600090815260096020526040902054839060ff1615612cc25760405162461bcd60e51b815260206004820152600e60248201526d1059191c995cdcc819195b9a595960921b6044820152606401610b16565b6001600160a01b038316600090815260096020526040902054839060ff1615612d1e5760405162461bcd60e51b815260206004820152600e60248201526d1059191c995cdcc819195b9a595960921b6044820152606401610b16565b61288b565b6000806000806000612d3587876130c1565b6001600160a01b038e166000908152600f602052604090205494995092975090955093509150851115612d7a5760405162461bcd60e51b8152600401610b169061351f565b6001600160a01b0389166000908152600f602052604081208054879290612da29084906134f1565b90915550506001600160a01b0388166000908152600f602052604081208054869290612dcf90849061338e565b90915550612de0905060118a6116ef565b15612e4b576001600160a01b038916600090815260106020526040902054871115612e1d5760405162461bcd60e51b8152600401610b169061351f565b6001600160a01b03891660009081526010602052604081208054899290612e459084906134f1565b90915550505b612e566011896116ef565b15612e89576001600160a01b03881660009081526010602052604081208054849290612e8390849061338e565b90915550505b612e938382613121565b876001600160a01b0316896001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612ed891815260200190565b60405180910390a38515612f2a57886001600160a01b03167f9ffbf50289a7a68340713701e9c2c0b22a6edc0b16140bf4d3ced3fcd0ba128387604051612f2191815260200190565b60405180910390a25b505050505050505050565b6001600160a01b0382166000908152600b602052604090205460ff1661289d57600a54612f6183610e76565b111561289d5760405162461bcd60e51b815260206004820152601b60248201527f416e74695768616c653a2062616c616e636520746f6f206869676800000000006044820152606401610b16565b600d54600c546000918291825b612fc6601161173e565b811015613090576000612fda601183611748565b6001600160a01b0381166000908152600f602052604090205490915084108061301a57506001600160a01b03811660009081526010602052604090205483105b1561303157600d54600c5495509550505050509091565b6001600160a01b0381166000908152600f602052604090205461305490856134f1565b6001600160a01b03821660009081526010602052604090205490945061307a90846134f1565b925050808061308890613565565b915050612fbc565b50600c54600d546130a191906134cf565b8210156130b857600d54600c549350935050509091565b90939092509050565b6000806000806000806130d2612c43565b905060006130e0828a6134b8565b905060006130ee838a6134b8565b905060006130fc82846134f1565b905082818361310b8d8f6134f1565b929e919d509b919a509098509650505050505050565b81600d600082825461313391906134f1565b9250508190555080600e600082825461314c919061338e565b90915550505050565b6001600160a01b0381168114610d5457600080fd5b8015158114610d5457600080fd5b6000806040838503121561318b57600080fd5b823561319681613155565b915060208301356131a68161316a565b809150509250929050565b600080604083850312156131c457600080fd5b82356131cf81613155565b946020939093013593505050565b600060208083528351808285015260005b8181101561320a578581018301518582016040015282016131ee565b506000604082860101526040601f19601f8301168501019250505092915050565b6000806040838503121561323e57600080fd5b50508035926020909101359150565b60006020828403121561325f57600080fd5b813561170d81613155565b60006020828403121561327c57600080fd5b5035919050565b60008060006060848603121561329857600080fd5b83356132a381613155565b925060208401356132b381613155565b929592945050506040919091013590565b6000602082840312156132d657600080fd5b813561170d8161316a565b600060e082840312156132f357600080fd5b50919050565b6000806040838503121561330c57600080fd5b823561331781613155565b915060208301356131a681613155565b60006020828403121561333957600080fd5b815161170d8161316a565b600181811c9082168061335857607f821691505b6020821081036132f357634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115610cc757610cc7613378565b6020808252600b908201526a105b1c9958591e481cd95d60aa1b604082015260600190565b6000602082840312156133d857600080fd5b815161170d81613155565b803561ffff811681146133f557600080fd5b919050565b600060e0828403121561340c57600080fd5b60405160e0810181811067ffffffffffffffff8211171561343d57634e487b7160e01b600052604160045260246000fd5b604052613449836133e3565b8152613457602084016133e3565b6020820152613468604084016133e3565b6040820152613479606084016133e3565b606082015261348a608084016133e3565b608082015261349b60a084016133e3565b60a08201526134ac60c084016133e3565b60c08201529392505050565b8082028115828204841417610cc757610cc7613378565b6000826134ec57634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610cc757610cc7613378565b61ffff82811682821603908082111561265357612653613378565b60208082526026908201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604082015265616c616e636560d01b606082015260800190565b60006001820161357757613577613378565b5060010190565b61ffff81811683821601908082111561265357612653613378565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156136155784516001600160a01b0316835293830193918301916001016135f0565b50506001600160a01b03969096166060850152505050608001529392505050565b60008060006060848603121561364b57600080fd5b835192506020840151915060408401519050925092509256fea264697066735822122070c85e3921b15b4138ccb2a0aa825d6de4280731c47c36f695e274674a0ee16d64736f6c63430008110033

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

0000000000000000000000004752ba5dbc23f44d87826276bf6fd6b1c372ad24000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009c4000000000000000000000000000000000000000000000000000000000000138800000000000000000000000000000000000000000000000000000000000009c40000000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : swapRouter_ (address): 0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24
Arg [1] : feeConfiguration_ (tuple):
Arg [1] : buyFees (uint16): 100
Arg [2] : sellFees (uint16): 200
Arg [3] : transferFees (uint16): 0
Arg [4] : burnFeeRatio (uint16): 2500
Arg [5] : rewardsFeeRatio (uint16): 5000
Arg [6] : liquidityFeeRatio (uint16): 2500
Arg [7] : collectorsFeeRatio (uint16): 0


-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000004752ba5dbc23f44d87826276bf6fd6b1c372ad24
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000c8
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 00000000000000000000000000000000000000000000000000000000000009c4
Arg [5] : 0000000000000000000000000000000000000000000000000000000000001388
Arg [6] : 00000000000000000000000000000000000000000000000000000000000009c4
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000000


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.