false
true
0

Contract Address Details

0x483d1cc3992cAc48303b7585D061e1B20a0865C4

Token
YieldX (YLDX)
Creator
0x7dc818–79b113 at 0xbb296a–c0b9c7
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
9 Transactions
Transfers
168 Transfers
Gas Used
662,202
Last Balance Update
26310350
Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB 0x8577f0fb9d709d5bebd808dddd0094fbaec667b4.
All metadata displayed below is from that contract. In order to verify current contract, click Verify & Publish button
Verify & Publish
Contract name:
TokenTax




Optimization enabled
true
Compiler version
v0.8.31+commit.fd3a2265




Optimization runs
1
Verified at
2026-04-17T02:03:22.578939Z

contracts/Tokens/TokenTaxV2.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "./interfaces/TokenTypes.sol";

interface IWETH_0 {
    function withdraw(uint256 wad) external;
}

interface ISmartTokenFactory {
    function FEE() external view returns (uint256);
    function WALLET() external view returns (address);
    function NEON_LP_FEE() external view returns (uint256);
    function NEON_LP_RECEIVER() external view returns (address);
}
interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(
        address sender,
        uint256 balance,
        uint256 needed
    );

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol

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

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

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

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

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

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

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

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

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

// lib/openzeppelin-contracts/contracts/utils/Context.sol

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

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

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

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

    uint256 private _status;

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

    constructor() {
        _status = NOT_ENTERED;
    }

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

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

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

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

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

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

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

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

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}
interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

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

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

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

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

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

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

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

    function initialize(address, address) external;
}

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

// lib/openzeppelin-contracts/contracts/access/Ownable.sol

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

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

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

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

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

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

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

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

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

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

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

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

// lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol

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

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

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

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

// lib/v2-periphery/contracts/interfaces/IUniswapV2Router02.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;
}

// contracts/Tokens/Manager.sol
contract Manager {
    // For yield tax tokens
    struct UserYield {
        uint256 reflectionDebt;
    }
    struct YieldToken {
        address tokenAddress;
        uint256 reflectionsPerShareAmount;
    }
    YieldToken[] internal yieldTokens;

    // (gas) Promoted to compile-time constants so every hot-path read becomes
    // a PUSH instead of an SLOAD. Safe because TokenTax is non-upgradeable and
    // freshly deployed per createToken — storage layout of live tokens is
    // unaffected (they keep the old slots baked into their own bytecode).
    uint256 internal constant PRECISION = 10 ** 28;
    uint256 internal reflectionsPerShareAmount;
    uint256 internal wethYieldBalance;
    address internal constant helpers = 0xd3397b405A2272F5C27fc673BE20579f22f59D6C;
    address internal constant wethAddress = 0xA1077a294dDE1B09bB078844df40758a5D0f9a27; // WPLS on PulseChain

    mapping(address => uint256) internal reflectionDebt;
    mapping(address => bool) public isReflectionExcluded;
    mapping(address => mapping(address => UserYield)) internal userYields;
    mapping(address => uint256[]) internal yieldTokenReflectionDebts;

    bool internal inSwap;

    modifier lockSwap() {
        inSwap = true;
        _;
        inSwap = false;
    }

    // (gas) Former assignments moved to constant declarations above.
    constructor() {}

    // ------------------------------------------ REFLECTIONS -------------------------------------------------//
    function getCurrentReflectionsPerShareAmount()
        external
        view
        returns (uint256)
    {
        return reflectionsPerShareAmount;
    }

    function isExcludedFromReflections(
        address account
    ) public view returns (bool) {
        return isReflectionExcluded[account];
    }

    function pendingReflections(address account) public view returns (uint256) {
        if (isExcludedFromReflections(account)) {
            return 0;
        }
        return cleanPendingReflections(account);
    }

    function cleanPendingReflections(
        address account
    ) internal view returns (uint256) {
        return
            Helpers(helpers).cleanPendingReflections(
                account,
                address(this),
                reflectionsPerShareAmount,
                reflectionDebt[account],
                PRECISION
            );
    }

    function updateAndClaimReflections(
        address from,
        address to,
        address deployer
    )
        internal
        returns (uint256 fromAmount, uint256 toAmount, uint256 deployerAmount)
    {
        if (from == to) {
            fromAmount = isExcludedFromReflections(from)
                ? 0
                : pendingReflections(from);
            toAmount = 0; // Set to zero to avoid double claiming
        } else {
            fromAmount = isExcludedFromReflections(from)
                ? 0
                : pendingReflections(from);
            toAmount = isExcludedFromReflections(to)
                ? 0
                : pendingReflections(to);
        }
        deployerAmount = cleanPendingReflections(deployer);
        reflectionDebt[deployer] = reflectionsPerShareAmount;
        reflectionDebt[from] = reflectionsPerShareAmount;
        reflectionDebt[to] = reflectionsPerShareAmount;
    }

    // function tokenPendingReflections() public view returns (uint256) {
    //     uint256 currentBalance = IERC20(address(this)).balanceOf(address(this));
    //     uint256 newReflectionDebt = reflectionsPerShareAmount;
    //     if (newReflectionDebt <= reflectionDebt[address(this)]) {
    //         return 0;
    //     }
    //     return (newReflectionDebt - reflectionDebt[address(this)]) * currentBalance / PRECISION;
    // }

    // ------------------------------------------ YIELD TOKENS REFLECTIONS -------------------------------------------------//

    function addYieldToken(
        address tokenAddress
    ) internal returns (uint256 tokenIndex) {
        for (uint256 i = 0; i < yieldTokens.length; i++) {
            if (yieldTokens[i].tokenAddress == tokenAddress) {
                return i;
            }
        }

        yieldTokens.push(
            YieldToken({
                tokenAddress: tokenAddress,
                reflectionsPerShareAmount: 0
            })
        );

        return yieldTokens.length - 1;
    }

    function pendingYields(
        address account,
        uint256 tokenIndex
    ) public view returns (uint256) {
        if (tokenIndex >= yieldTokenReflectionDebts[account].length) {
            return 0;
        }
        return
            Helpers(helpers).pendingYields(
                account,
                address(this),
                yieldTokens[tokenIndex].reflectionsPerShareAmount,
                yieldTokenReflectionDebts[account][tokenIndex],
                PRECISION
            );
    }

    function updateAndClaimYield(
        address from,
        address to,
        address deployer
    ) internal {
        for (uint256 i = 0; i < yieldTokens.length; i++) {
            while (yieldTokenReflectionDebts[from].length <= i) {
                yieldTokenReflectionDebts[from].push(
                    yieldTokens[i].reflectionsPerShareAmount
                );
            }
            while (yieldTokenReflectionDebts[to].length <= i) {
                yieldTokenReflectionDebts[to].push(
                    yieldTokens[i].reflectionsPerShareAmount
                );
            }
            while (yieldTokenReflectionDebts[deployer].length <= i) {
                yieldTokenReflectionDebts[deployer].push(
                    yieldTokens[i].reflectionsPerShareAmount
                );
            }

            uint256 fromAmount = isExcludedFromReflections(from)
                ? 0
                : pendingYields(from, i);
            uint256 toAmount = 0; // Initialize to 0

            if (from != to) {
                toAmount = isExcludedFromReflections(to)
                    ? 0
                    : pendingYields(to, i);
            }

            uint256[] memory transferAmounts = new uint256[](2);
            address[] memory recipients = new address[](2);
            uint256 recipientCount = 0;
            if (fromAmount > 0) {
                transferAmounts[recipientCount] = fromAmount;
                recipients[recipientCount] = from;
                recipientCount++;
            }
            if (toAmount > 0) {
                transferAmounts[recipientCount] = toAmount;
                recipients[recipientCount] = to;
                recipientCount++;
            }

            for (uint256 j = 0; j < recipientCount; j++) {
                if (transferAmounts[j] > 0) {
                    try
                        IERC20(yieldTokens[i].tokenAddress).transfer(
                            recipients[j],
                            transferAmounts[j]
                        )
                    {
                        if (yieldTokens[i].tokenAddress == wethAddress) {
                            wethYieldBalance -= transferAmounts[j];
                        }
                        yieldTokenReflectionDebts[recipients[j]][
                            i
                        ] = yieldTokens[i].reflectionsPerShareAmount;
                    } catch {}
                }
            }
        }
    }

    function getYieldTokens() public view returns (YieldToken[] memory) {
        return yieldTokens;
    }

    function getYieldTokenReflectionDebts(
        address account
    ) public view returns (uint256[] memory) {
        return yieldTokenReflectionDebts[account];
    }
}

// contracts/Tokens/ERC20.sol

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

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

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

        emit Transfer(from, to, value);
    }

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

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

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

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

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

// contracts/Tokens/SmartTrader.sol
contract SmartTrader is Ownable {
    constructor() Ownable(msg.sender) {}

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        address _router,
        address _receiver,
        uint256 amountIn,
        address[] memory path
    ) public {
        IERC20(path[0]).transferFrom(msg.sender, address(this), amountIn);
        IERC20(path[0]).approve(_router, amountIn);

        IUniswapV2Router02(_router)
            .swapExactTokensForTokensSupportingFeeOnTransferTokens(
                amountIn,
                0,
                path,
                address(this),
                block.timestamp
            );

        uint256 receivedAmount = IERC20(path[path.length - 1]).balanceOf(
            address(this)
        );
        IERC20(path[path.length - 1]).transfer(_receiver, receivedAmount);
    }

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        address _router,
        address _receiver,
        uint256 amountIn,
        address[] calldata path
    ) public {
        IERC20(path[0]).transferFrom(msg.sender, address(this), amountIn);
        IERC20(path[0]).approve(_router, amountIn);

        IUniswapV2Router02(_router)
            .swapExactTokensForETHSupportingFeeOnTransferTokens(
                amountIn,
                0,
                path,
                _receiver,
                block.timestamp
            );

        payable(_receiver).transfer(address(this).balance);
    }

    function buyToken(
        address _router,
        address _receiver,
        uint256 amountIn,
        address[] memory path
    ) public {
        IERC20(path[0]).transferFrom(msg.sender, address(this), amountIn);
        IERC20(path[0]).approve(_router, amountIn);
        IUniswapV2Router02(_router)
            .swapExactTokensForTokensSupportingFeeOnTransferTokens(
                amountIn,
                0,
                path,
                _receiver,
                block.timestamp
            );
    }

    function addLiquidity(
        address _router,
        address tokenA,
        address tokenB,
        uint256 amountA,
        uint256 amountB,
        address lpReceiver
    ) public {
        IERC20(tokenA).transferFrom(msg.sender, address(this), amountA);
        IERC20(tokenB).transferFrom(msg.sender, address(this), amountB);
        IERC20(tokenA).approve(_router, amountA);
        IERC20(tokenB).approve(_router, amountB);
        IUniswapV2Router02(_router).addLiquidity(
            tokenA, tokenB, amountA, amountB, 0, 0, lpReceiver, block.timestamp
        );
        // Return any dust
        uint256 dustA = IERC20(tokenA).balanceOf(address(this));
        if (dustA > 0) IERC20(tokenA).transfer(msg.sender, dustA);
        uint256 dustB = IERC20(tokenB).balanceOf(address(this));
        if (dustB > 0) IERC20(tokenB).transfer(msg.sender, dustB);
    }

    function withdrawPLS() external onlyOwner {
        uint256 balance = address(this).balance;
        require(balance > 0, "No PLS to withdraw");
        payable(owner()).transfer(balance);
    }

    function withdrawToken(address tokenAddress) external onlyOwner {
        IERC20 token = IERC20(tokenAddress);
        uint256 balance = token.balanceOf(address(this));
        require(balance > 0, "No tokens to withdraw");
        token.transfer(owner(), balance);
    }

    receive() external payable {}
}
interface IWETH_1 {
    function withdraw(uint256 wad) external;
}
contract TokenTax is ERC20, Ownable, Manager {
    //
    //       ███╗   ██╗███████╗██╗  ██╗██╗ ██████╗ ███╗   ██╗
    //       ████╗  ██║██╔════╝╚██╗██╔╝██║██╔═══██╗████╗  ██║
    //       ██╔██╗ ██║█████╗   ╚███╔╝ ██║██║   ██║██╔██╗ ██║
    //       ██║╚██╗██║██╔══╝   ██╔██╗ ██║██║   ██║██║╚██╗██║
    //       ██║ ╚████║███████╗██╔╝ ██╗██║╚██████╔╝██║ ╚████║
    //       ╚═╝  ╚═══╝╚══════╝╚═╝  ╚═╝╚═╝ ╚═════╝ ╚═╝  ╚═══╝
    //
    //            * .    *       *    .      * .      *
    //     .   *         *              .        .  *
    //                    .                *         .
    //    .    *     *         *    .   *          .  *
    //         _____                         _____
    //       .|     |.    *     .   *     .|     |.
    //       ||     ||        .          *||     ||
    //       || ___ ||  *         .       || ___ ||
    //  *    |:_____:|        *           |:_____:|
    //       |_______|    .   *      *    |_______|. *
    //  .    | .   . |              .     | .   . |
    //       | .   . |   *    .           | .   . |    *
    //       '._____.'.       *     *    .'._____.'.
    //
    // Revolutionary Hyper-Deflationary and Bonded Liquidity Ecosystem
    //
    // Telegram: https://t.me/NexionPulse
    // Website: https://nexionpulse.com/
    // X: https://x.com/nexionpulse
    // Contract: 0xF2Da3942616880E52e841E5C504B5A9Fba23FFF0
    //

    uint256 public initialSupply;
    bool public tradingEnabled;
    uint64 public enableTradingAt; // timestamp for auto-enable (0 = manual only)

    error TradingDisabled();
    error AlreadyEnabled();
    event TradingEnabled();

    address payable private smartTrader;
    address private deployer;
    address private factory;

    address[] private routers = [
        0x98bf93ebf5c380C0e6Ae8e192A7e2AE08edAcc02,
        0x165C3410fC91EF562C50559f7d2289fEbed552d9,
        0xcC73b59F8D7b7c532703bDfea2808a28a488cF47,
        0xeB45a3c4aedd0F47F345fB4c8A1802BB5740d725
    ];
    mapping(address => bool) isTaxExcluded;
    /// @dev (G2) Deprecated storage slot — must remain to preserve UUPS layout.
    ///      Previously written on every taxed transfer; now passed as a function
    ///      parameter through processAccumulatedTaxes / Helpers.getProcessingAmount.
    ///      Reads still happen via the legacy internal getProcessingAmount(uint256)
    ///      helper below, but no on-path code writes to this slot anymore.
    uint256 private __deprecated_currentSwapAmount;
    uint256 private accumulatedFee;
    // Parallel platform-style bucket for the Neon LP autoBuy/autoLP feed.
    // Funded the same way as `accumulatedFee` (bps of each user tax) but
    // routed to NEON_LP_RECEIVER instead of getWallet() during processAccumulatedTaxes.
    // Never cannibalises the creator's tax bucket.
    uint256 private accumulatedNeonFee;

    bool private shouldAccumulateFee;
    bool private reflectionsEnabled;
    bool private yieldEnabled;
    bool private firstPairInteractionHappened;
    bool private processedTaxesInTx;

    // Add all the events for tax tracking
    event TaxCollected(
        uint256 indexed taxId,
        Helpers.TaxType taxType,
        Helpers.TaxMoment taxMoment,
        address from,
        address to,
        uint256 amount,
        uint256 timestamp
    );
    event noRouter();

    event BurnTaxProcessed(uint256 amount, uint256 timestamp);

    event ExternalBurnProcessed(
        uint256 tokenAmount,
        uint256 taxid,
        uint256 wethAmount,
        address receiver,
        address tokenToBurn,
        uint256 timestamp
    );

    event ReflectionTaxProcessed(
        uint256 amount,
        uint256 newReflectionsPerShareAmount,
        uint256 timestamp
    );

    event ReflectionDistributed(
        address from,
        address to,
        uint256 fromAmount,
        uint256 toAmount,
        uint256 deployerAmount,
        uint256 reflectionsPerShareAmount,
        uint256 timestamp
    );

    event YieldTaxProcessed(
        uint256 tokenAmount,
        uint256 wethAmount,
        address yieldTokenAddress,
        uint256 timestamp
    );

    event YieldDistributed(
        address tokenAddress,
        address recipient,
        uint256 amount,
        uint256 reflectionsPerShareAmount,
        uint256 timestamp
    );

    Helpers.Tax[] public taxes;
    error ZeroTaxPercentage();

    uint256 public totalBurned; // Track burn taxes
    uint256 public totalSupport; // Track external burn taxes
    uint256 public totalReflection; // Track reflection taxes
    uint256 public totalYield; // Track yield taxes
    uint256 public totalLiquify; // Track liquify taxes

    address internal constant deadAddress = 0x000000000000000000000000000000000000dEaD;

    constructor(
        DeployTokenParams memory p
    ) ERC20(p.name_, p.symbol_) Ownable(p.owner_) Manager() {
        tradingEnabled = p.tradingEnabled;
        enableTradingAt = p.enableTradingAt;
        _mint(p.mintTo, p.initialSupply);

        // Burn on deploy: real _burn that reduces totalSupply
        if (p.burnOnDeployPct > 0) {
            uint256 burnAmount = (p.initialSupply * p.burnOnDeployPct) / 10000;
            _burn(p.mintTo, burnAmount);
        }

        // Transfer vested tokens to vesting contract
        if (p.vestAmount > 0 && p.vestingContract != address(0)) {
            super._transfer(p.mintTo, p.vestingContract, p.vestAmount);
        }

        deployer = p.mintTo;
        initialSupply = p.initialSupply;
        smartTrader = payable(p.smartTrader);
        factory = p.factory;

        // Inline taxesInitialize (can't rely on deployed Helpers for Liquify enum)
        // (G4) Zero-percentage check now lives inside _initializeTaxes; the
        // duplicate post-loop has been removed.
        _initializeTaxes(p.taxes);

        inititlizeTaxExclusions();

        if (reflectionsEnabled || yieldEnabled)
            initializeReflectionExclusions();

        IERC20(wethAddress).approve(smartTrader, 2 ** 256 - 1);
        _approve(address(this), smartTrader, 2 ** 256 - 1);
    }

    function _initializeTaxes(Helpers.Tax[] memory _taxes) internal {
        uint256 totalTaxPct;

        for (uint256 i; i < _taxes.length; i++) {
            taxes.push(_taxes[i]);
            taxes[i].id = i;

            // (G4) Hoisted from the second constructor loop
            if (_taxes[i].percentage == 0) revert ZeroTaxPercentage();
            require(_taxes[i].percentage <= 5000, "Tax percentage too high");

            if (_taxes[i].taxMoment == Helpers.TaxMoment.Both) {
                totalTaxPct += _taxes[i].percentage * 2;
            } else {
                totalTaxPct += _taxes[i].percentage;
            }

            if (_taxes[i].taxType == Helpers.TaxType.Reflection) {
                reflectionsEnabled = true;
            }

            if (_taxes[i].taxType == Helpers.TaxType.Yield) {
                yieldEnabled = true;
                if (_taxes[i].tokenAddress != address(0)) {
                    addYieldToken(_taxes[i].tokenAddress);
                }
            }

            if (_taxes[i].taxType == Helpers.TaxType.ExternalBurn) {
                require(_taxes[i].receiver != address(0), "ExternalBurn: receiver cannot be zero");
                require(_taxes[i].tokenAddress != address(0), "ExternalBurn: tokenAddress cannot be zero");
                shouldAccumulateFee = true;
            } else if (_taxes[i].taxType == Helpers.TaxType.Dev) {
                require(_taxes[i].receiver != address(0), "Dev: receiver cannot be zero");
                if (_taxes[i].rewardInPls) {
                    shouldAccumulateFee = true;
                }
            } else if (_taxes[i].taxType == Helpers.TaxType.Yield) {
                require(_taxes[i].tokenAddress != address(0), "Yield: tokenAddress cannot be zero");
                shouldAccumulateFee = true;
            } else if (_taxes[i].taxType == Helpers.TaxType.Liquify) {
                shouldAccumulateFee = true;
            }
        }

        require(totalTaxPct <= 8000, "Total tax percentage too high");
    }

    function _transfer(
        address from,
        address to,
        uint256 value
    ) internal override {
        processedTaxesInTx = false;

        // (gas #7) Cache `tradingEnabled` and `isTaxExcluded[from]` once —
        // both are touched multiple times below, and caching saves 2 SLOADs
        // per transfer on the common taxed path.
        bool _trading = tradingEnabled;
        bool _fromExcluded = isTaxExcluded[from];

        // Auto-enable trading if timer has passed
        if (!_trading && enableTradingAt > 0 && block.timestamp >= enableTradingAt) {
            tradingEnabled = true;
            _trading = true;
            emit TradingEnabled();
        }

        if (isDeadAddress(to)) {
            super._burn(from, value);
            return;
        }

        // Block non-excluded transfers when trading is disabled
        if (!_trading && !_fromExcluded) revert TradingDisabled();

        bool _isPairTo = isPair(to);

        if (
            taxes.length == 0 ||
            !firstPairInteractionHappened ||
            _fromExcluded ||
            isTaxExcluded[to] ||
            inSwap
        ) {
            if (!firstPairInteractionHappened && _isPairTo)
                firstPairInteractionHappened = true;

            _claimYield(from, to);
            super._transfer(from, to, value);
            return;
        }

        if (_isPairTo && !isReflectionExcluded[to])
            isReflectionExcluded[to] = true;

        // (gas #3A) Compute isBuy/isSell ONCE here and thread them through
        // processTaxes + the post-tax gating block. Prior code called
        // Helpers.isBuy twice per taxed transfer (once inside processTaxes,
        // once after). Now it's a single STATICCALL, with isSell only
        // evaluated when isBuy is false (preserves the G3 short-circuit).
        bool _isBuy  = isBuy(from, to);
        bool _isSell = _isBuy ? false : isSell(from, to);

        // (G2) `value` is plumbed directly through processAccumulatedTaxes
        // instead of via the deprecated currentSwapAmount storage slot.
        uint256 amountAfterTaxs = processTaxes(from, to, value, _isBuy, _isSell);

        // (gas #6) `hasAccumulatedTaxes()` was provably dead: it only returned
        // true when some tax.amountAccumulated > 0, and amountAccumulated is
        // only written by the four processors (ExternalBurn / Yield / Liquify
        // / Dev+rewardInPls) that set `shouldAccumulateFee = true` in the
        // constructor. `firstPairInteractionHappened` and `!inSwap` are also
        // already guaranteed by the early-return guard above. Collapsed to a
        // single boolean check.
        if (shouldAccumulateFee && !processedTaxesInTx && !_isBuy) {
            processAccumulatedTaxes(value);
            processedTaxesInTx = true;
        }

        _claimYield(from, to);
        _claimReflections(from, to);

        super._transfer(from, to, amountAfterTaxs);
    }

    /// @dev Bundle of loop-invariant context for _processOneTaxLeg. Passed
    ///      as a single memory struct to keep the per-call argument count
    ///      under the non-via-ir stack-too-deep ceiling.
    struct TaxLegCtx {
        address from;
        address to;
        uint256 amount;
        bool isBuy;
        bool isSell;
        uint256 neonFeeBps;
        uint256 fee;
    }

    function processTaxes(
        address from,
        address to,
        uint256 amount,
        bool _isBuy,
        bool _isSell
    ) internal returns (uint256) {
        uint256 totalTaxAmount;
        uint256 totalFee;
        uint256 totalNeonFee;

        TaxLegCtx memory ctx;
        ctx.from = from;
        ctx.to = to;
        ctx.amount = amount;

        // (gas #3A) isBuy/isSell are now computed once by the caller and
        // passed in, eliminating a duplicate Helpers.isBuy STATICCALL.
        // The G3 short-circuit is preserved at the caller.
        ctx.isBuy = _isBuy;
        ctx.isSell = _isSell;

        // Parallel Neon LP fee, taken in bps of each user-tax slice (NOT volume,
        // NOT from the platform Fee bucket, NOT from creator's leftover WPLS).
        // Only fires when shouldAccumulateFee is true — i.e. the token has a
        // tax type that requires the WPLS swap pipeline. Otherwise the neon
        // tokens would have no path out and would just sit in the contract.
        if (shouldAccumulateFee && getNeonLpReceiver() != address(0)) {
            ctx.neonFeeBps = getNeonLpFee();
        }

        // (G1) Read the platform FEE once per transfer instead of once per
        //      tax leg. Saves N-1 STATICCALLs to the factory per taxed trade.
        // (#4) Cache the taxes array to memory once. processTaxes only reads
        //      immutable fields (taxType/taxMoment/percentage/receiver/etc.);
        //      writes to amountAccumulated still go through storage in
        //      processTaxType via taxes[tax.id], so accounting is unaffected.
        ctx.fee = getFee();
        Helpers.Tax[] memory _cachedTaxes = taxes;
        uint256 len = _cachedTaxes.length;

        for (uint256 i; i < len; i++) {
            (uint256 _taxAmount, uint256 _Fee, uint256 _neonFee) = _processOneTaxLeg(
                ctx, _cachedTaxes[i]
            );
            totalTaxAmount += _taxAmount;
            totalFee       += _Fee;
            totalNeonFee   += _neonFee;
        }

        if (totalFee > 0) {
            if (shouldAccumulateFee) {
                super._transfer(from, address(this), totalFee);
                accumulatedFee += totalFee;
            } else {
                super._transfer(from, getWallet(), totalFee);
            }
        }

        if (totalNeonFee > 0) {
            // Neon fee always accumulates for the swap pipeline (gated above
            // on shouldAccumulateFee, so we know the swap path will run).
            super._transfer(from, address(this), totalNeonFee);
            accumulatedNeonFee += totalNeonFee;
        }

        return amount - totalTaxAmount - totalFee - totalNeonFee;
    }

    /// @dev Per-tax-leg helper extracted from processTaxes() to keep that
    ///      frame under the stack-too-deep limit. Computes the user-tax /
    ///      dev-fee / neon-fee triple, routes the user-tax portion to its
    ///      destination, and returns the three amounts so the caller can
    ///      accumulate totals. Loop-invariant context (from/to/amount/
    ///      isBuy/isSell/neonFeeBps/fee) is bundled into TaxLegCtx to keep
    ///      the argument count below the non-via-ir stack ceiling.
    function _processOneTaxLeg(
        TaxLegCtx memory ctx,
        Helpers.Tax memory tax
    ) internal returns (uint256 taxAmount, uint256 Fee, uint256 neonFee) {
        bool fired;
        if (tax.taxMoment == Helpers.TaxMoment.Both) {
            (taxAmount, Fee) = calculateTaxAmount(ctx.amount, tax, ctx.fee);
            fired = true;
        } else if (tax.taxMoment == Helpers.TaxMoment.Buy && ctx.isBuy) {
            (taxAmount, Fee) = calculateTaxAmount(ctx.amount, tax, ctx.fee);
            fired = true;
        } else if (tax.taxMoment == Helpers.TaxMoment.Sell && ctx.isSell) {
            (taxAmount, Fee) = calculateTaxAmount(ctx.amount, tax, ctx.fee);
            fired = true;
        }
        if (!fired) return (0, 0, 0);

        // Slice neon out of the user-tax portion (NOT out of dev Fee).
        if (ctx.neonFeeBps > 0 && taxAmount > 0) {
            neonFee = (taxAmount * ctx.neonFeeBps) / 10000;
            taxAmount -= neonFee;
        }

        processTaxType(ctx.from, ctx.to, taxAmount, tax);
    }

    /// @dev (G1) Now takes the cached platform fee as a parameter rather than
    ///      reading it via an external call to the factory on every call.
    function calculateTaxAmount(
        uint256 originalAmount,
        Helpers.Tax memory tax,
        uint256 fee_
    ) internal view returns (uint256 taxAmount, uint256 Fee) {
        return
            Helpers(helpers).calculateTaxAmount(
                originalAmount,
                tax.percentage,
                fee_,
                true,
                10000
            );
    }

    /// @param to (#2) Real transfer recipient — used as the TaxCollected.to
    ///           field instead of msg.sender. Off-chain indexers reading the
    ///           previous (broken) field were always seeing the router on
    ///           swaps. New deployments emit the correct counterparty.
    function processTaxType(
        address from,
        address to,
        uint256 taxAmount,
        Helpers.Tax memory tax
    ) internal {
        // Emit tax collection event for all types
        emit TaxCollected(
            tax.id,
            tax.taxType,
            tax.taxMoment,
            from,
            to,
            taxAmount,
            block.timestamp
        );

        if (tax.taxType == Helpers.TaxType.Burn) {
            processBurnTax(from, taxAmount);
        } else if (tax.taxType == Helpers.TaxType.Reflection) {
            processReflectionTax(from, taxAmount);
        } else if (tax.taxType == Helpers.TaxType.Dev) {
            processTreasuryTax(from, taxAmount, tax);
        } else if (tax.taxType == Helpers.TaxType.ExternalBurn) {
            processSupportTax(from, taxAmount, tax);
        } else if (tax.taxType == Helpers.TaxType.Yield) {
            processYieldTax(from, taxAmount, tax);
        } else if (tax.taxType == Helpers.TaxType.Liquify) {
            processLiquifyTax(from, taxAmount, tax);
        }
    }

    function burn(uint256 amount) public {
        totalBurned += amount;
        emit BurnTaxProcessed(amount, block.timestamp);
        super._burn(msg.sender, amount);
    }

    function processBurnTax(address from, uint256 taxAmount) internal {
        totalBurned += taxAmount;
        emit BurnTaxProcessed(taxAmount, block.timestamp);
        super._burn(from, taxAmount);
    }

    function processTreasuryTax(
        address from,
        uint256 taxAmount,
        Helpers.Tax memory tax
    ) internal {
        if (!isTaxExcluded[tax.receiver]) isTaxExcluded[tax.receiver] = true;
        if (tax.rewardInPls) {
            super._transfer(from, address(this), taxAmount);
            taxes[tax.id].amountAccumulated += taxAmount;
        } else {
            super._transfer(from, tax.receiver, taxAmount);
        }
    }

    function processReflectionTax(address from, uint256 taxAmount) internal {
        super._transfer(from, address(this), taxAmount);
        uint256 supply = totalSupply() - balanceOf(address(this));

        if (supply > 0) {
            reflectionsPerShareAmount += (taxAmount * PRECISION) / supply;
            totalReflection += taxAmount;
        }

        emit ReflectionTaxProcessed(
            taxAmount,
            reflectionsPerShareAmount,
            block.timestamp
        );
    }

    function processSupportTax(
        address from,
        uint256 taxAmount,
        Helpers.Tax memory tax
    ) internal lockSwap {
        super._transfer(from, address(this), taxAmount);
        taxes[tax.id].amountAccumulated += taxAmount;
        totalSupport += taxAmount;
        emit ExternalBurnProcessed(
            taxAmount,
            tax.id,
            0,
            tax.receiver,
            tax.tokenAddress,
            block.timestamp
        );
    }

    function processYieldTax(
        address from,
        uint256 taxAmount,
        Helpers.Tax memory tax
    ) internal lockSwap {
        super._transfer(from, address(this), taxAmount);
        taxes[tax.id].amountAccumulated += taxAmount;
        totalYield += taxAmount;
        emit YieldTaxProcessed(
            taxAmount,
            0, // wethAmount (will be updated when processed)
            tax.tokenAddress,
            block.timestamp
        );
    }

    function processLiquifyTax(
        address from,
        uint256 taxAmount,
        Helpers.Tax memory tax
    ) internal lockSwap {
        super._transfer(from, address(this), taxAmount);
        taxes[tax.id].amountAccumulated += taxAmount;
        totalLiquify += taxAmount;
    }

    function processAccumulatedTaxes(uint256 swapAmount) internal lockSwap {
        uint256 totalToSwap = 0;
        uint256 totalTokenTypes = 0;
        uint256 tl = taxes.length;
        bool[] memory taxesToProcess = new bool[](tl);
        uint256[] memory taxAmounts = new uint256[](tl);

        for (uint256 i; i < tl; i++) {
            Helpers.Tax storage tax = taxes[i];
            if (tax.amountAccumulated == 0) continue;
            if (
                tax.taxType == Helpers.TaxType.ExternalBurn ||
                (tax.taxType == Helpers.TaxType.Dev && tax.rewardInPls) ||
                tax.taxType == Helpers.TaxType.Yield ||
                tax.taxType == Helpers.TaxType.Liquify
            ) {
                (uint256 swapAmount, uint256 _newAccumulatedAmount) = Helpers(
                    helpers
                ).getProcessingAmount(tax.amountAccumulated, swapAmount);
                if (swapAmount > 0) {
                    uint256 amountToSwap = swapAmount;
                    uint256 finalAccumulatedAmount = _newAccumulatedAmount;

                    // For Liquify, only swap half — keep other half for liquidity
                    if (tax.taxType == Helpers.TaxType.Liquify) {
                        amountToSwap = swapAmount / 2;
                        finalAccumulatedAmount = _newAccumulatedAmount + (swapAmount - amountToSwap);
                    }

                    taxesToProcess[i] = true;
                    taxAmounts[i] = amountToSwap;
                    totalToSwap += amountToSwap;
                    totalTokenTypes++;
                    taxes[i].amountAccumulated = finalAccumulatedAmount;
                } else {
                    taxes[i].amountAccumulated = _newAccumulatedAmount;
                }
            }
        }

        (, /*address bestPair*/ address bestRouter) = Helpers(helpers)
            .getBestPair(address(this), wethAddress, routers);
        if (bestRouter == address(0)) {
            emit noRouter();
            return;
        }

        // Pull both platform buckets from storage. Scoped block so the
        // `newAcc*` temporaries don't pollute the outer stack frame.
        uint256 ToProcess;
        uint256 NeonToProcess;
        {
            uint256 newAcc;
            uint256 newAccNeon;
            (ToProcess, newAcc) = Helpers(helpers).getProcessingAmount(
                accumulatedFee, swapAmount
            );
            (NeonToProcess, newAccNeon) = Helpers(helpers).getProcessingAmount(
                accumulatedNeonFee, swapAmount
            );
            accumulatedFee     = newAcc;
            accumulatedNeonFee = newAccNeon;
        }

        totalToSwap += ToProcess;
        totalToSwap += NeonToProcess;
        if (totalToSwap == 0) return;

        // _approve(address(this), smartTrader, totalToSwap);
        try
            SmartTrader(smartTrader)
                .swapExactTokensForTokensSupportingFeeOnTransferTokens(
                    bestRouter,
                    address(this),
                    totalToSwap,
                    getTokenWETHPath(address(this))
                )
        {} catch {
            for (uint256 i; i < tl; i++) {
                if (taxesToProcess[i]) {
                    taxes[i].amountAccumulated += taxAmounts[i];
                }
            }
            accumulatedFee     += ToProcess;
            accumulatedNeonFee += NeonToProcess;
            return;
        }
        uint256 totalWethReceived = IERC20(wethAddress).balanceOf(
            address(this)
        ) - wethYieldBalance;

        // Pay dev wallet (FEE bps slice) + Neon LP receiver (NEON_LP_FEE bps
        // parallel slice) and shrink the WPLS pool down to the creator's share.
        // Helper extracted to keep this frame under the stack-too-deep limit.
        totalWethReceived -= _distributeFeesAndNeon(
            totalWethReceived, ToProcess, NeonToProcess, totalToSwap
        );

        totalToSwap -= ToProcess;
        totalToSwap -= NeonToProcess;
        if (totalWethReceived == 0) return;

        for (uint256 i; i < tl; i++) {
            if (!taxesToProcess[i] || taxAmounts[i] == 0) continue;

            uint256 wethPortion = (taxAmounts[i] * totalWethReceived) /
                totalToSwap;
            Helpers.Tax storage tax = taxes[i];

            if (tax.taxType == Helpers.TaxType.ExternalBurn) {
                emit ExternalBurnProcessed(
                    taxAmounts[i],
                    tax.id,
                    wethPortion,
                    tax.receiver,
                    tax.tokenAddress,
                    block.timestamp
                );
                processExternalBurnWeth(wethPortion, tax);
            } else if (tax.taxType == Helpers.TaxType.Dev && tax.rewardInPls) {
                sendWETH(wethPortion, tax.receiver);
            } else if (tax.taxType == Helpers.TaxType.Yield) {
                emit YieldTaxProcessed(
                    taxAmounts[i],
                    wethPortion,
                    tax.tokenAddress,
                    block.timestamp
                );
                processYieldWeth(wethPortion, tax);
            } else if (tax.taxType == Helpers.TaxType.Liquify) {
                processLiquifyWeth(wethPortion, tax);
            }
        }
    }

    /// @dev Pays the dev wallet share + the Neon LP share out of the just-swapped
    ///      WPLS pool. Returns total WPLS spent so the caller can shrink its pool.
    ///      Extracted from processAccumulatedTaxes() to keep that frame under the
    ///      stack-too-deep limit (we cannot use --via-ir per project rules).
    function _distributeFeesAndNeon(
        uint256 totalWethReceived,
        uint256 toProcess,
        uint256 neonToProcess,
        uint256 totalToSwap_
    ) internal returns (uint256 spent) {
        // Dev wallet — unchanged behaviour, full FEE bps cut.
        uint256 devSlice = (totalWethReceived * toProcess) / totalToSwap_;
        if (devSlice > 0) sendWETH(devSlice, getWallet());

        // Neon LP — parallel cut. Receiver is read at distribution time so a
        // mid-flight setNeonLpReceiver() always routes pending neon to the
        // latest configured contract. If receiver is unset, the corresponding
        // WPLS is left on the token (rescuable via rescueToken).
        uint256 neonSlice = (totalWethReceived * neonToProcess) / totalToSwap_;
        if (neonSlice > 0) {
            address neonRecv = getNeonLpReceiver();
            if (neonRecv != address(0)) sendWETH(neonSlice, neonRecv);
        }

        return devSlice + neonSlice;
    }

    function processExternalBurnWeth(
        uint256 wethAmount,
        Helpers.Tax memory tax
    ) internal {
        if (wethAmount == 0) return;

        if (tax.tokenAddress == wethAddress) {
            IERC20(wethAddress).transfer(tax.receiver, wethAmount);
            return;
        }
        (, /*address bestTargetPair*/ address bestTargetRouter) = Helpers(
            helpers
        ).getBestPair(wethAddress, tax.tokenAddress, routers);

        // IERC20(wethAddress).approve(smartTrader, 2**256-1);
        try
            SmartTrader(smartTrader).buyToken(
                bestTargetRouter,
                tax.receiver,
                wethAmount,
                getWETHBuyBurnPath(tax.tokenAddress)
            )
        {} catch {
            IERC20(wethAddress).transfer(tax.receiver, wethAmount);
        }
    }

    /// @dev KNOWN BUG (mitigated off-chain in the deployment UI):
    ///      On the success path of `withdraw`, the WPLS has already been
    ///      unwrapped to native PLS. If the subsequent `.call` fails (receiver
    ///      is a contract that rejects PLS — Safe with no `receive()`,
    ///      blacklist-bound contract, etc.), the fallback `transfer` of WETH
    ///      operates on a balance that no longer exists for this slice.
    ///      Two failure modes:
    ///        1. Hard revert if the contract holds no other WETH → bricks
    ///           every subsequent user transfer (processAccumulatedTaxes runs
    ///           inside _transfer with no try/catch wrapping it).
    ///        2. Silent dip into `wethYieldBalance` if yield reserves exist →
    ///           the next processAccumulatedTaxes computes
    ///           `weth.balanceOf(this) - wethYieldBalance` and underflows
    ///           (panic), permanently bricking tax processing for this token.
    ///      Trigger surfaces the UI cannot fully cover:
    ///        (a) factory `WALLET` (set by factory owner via setWallet)
    ///        (b) `NEON_LP_RECEIVER` (set by factory owner via setNeonLpReceiver)
    ///        (c) any receiver contract that becomes PLS-rejecting AFTER
    ///            deployment (multisig reconfig, paused flag, etc.)
    ///      The deployment UI validates per-token dev receivers can accept
    ///      PLS at create time, which mitigates the most common surface
    ///      (the dev receiver picked at create) but does NOT cover (a)/(b)/(c).
    ///      Long-term fix: re-wrap PLS via `IWETH(wethAddress).deposit{value: wethAmount}()`
    ///      before the fallback transfer, OR never unwrap and always send WETH.
    function sendWETH(uint256 wethAmount, address receiver) internal {
        if (wethAmount == 0) return;
        try IWETH_1(wethAddress).withdraw(wethAmount) {
            (bool success, ) = receiver.call{value: wethAmount}("");
            if (!success) {
                IERC20(wethAddress).transfer(receiver, wethAmount);
            } else {}
        } catch {
            IERC20(wethAddress).transfer(receiver, wethAmount);
        }
    }

    function processYieldWeth(
        uint256 wethAmount,
        Helpers.Tax memory tax
    ) internal {
        if (wethAmount == 0) return;

        if (tax.tokenAddress == wethAddress) {
            wethYieldBalance += wethAmount;
            uint256 tokenIndex = addYieldToken(tax.tokenAddress);
            uint256 supply = totalSupply() - balanceOf(address(this));
            if (supply > 0) {
                yieldTokens[tokenIndex].reflectionsPerShareAmount +=
                    (wethAmount * PRECISION) /
                    supply;

                emit YieldDistributed(
                    tax.tokenAddress,
                    address(this),
                    wethAmount,
                    yieldTokens[tokenIndex].reflectionsPerShareAmount,
                    block.timestamp
                );
            }
            return;
        }

        (, /*address bestTargetPair*/ address bestTargetRouter) = Helpers(
            helpers
        ).getBestPair(wethAddress, tax.tokenAddress, routers);

        uint256 initialTokenBalance = IERC20(tax.tokenAddress).balanceOf(
            address(this)
        );

        // IERC20(wethAddress).approve(smartTrader, wethAmount);
        try
            SmartTrader(smartTrader).buyToken(
                bestTargetRouter,
                address(this),
                wethAmount,
                getWETHBuyBurnPath(tax.tokenAddress)
            )
        {
            uint256 finalTokenBalance = IERC20(tax.tokenAddress).balanceOf(
                address(this)
            );
            uint256 boughtAmount = finalTokenBalance - initialTokenBalance;

            if (boughtAmount > 0) {
                uint256 tokenIndex = addYieldToken(tax.tokenAddress);
                uint256 supply = totalSupply() - balanceOf(address(this));
                if (supply > 0) {
                    yieldTokens[tokenIndex].reflectionsPerShareAmount +=
                        (boughtAmount * PRECISION) /
                        supply;

                    emit YieldDistributed(
                        tax.tokenAddress,
                        address(this),
                        boughtAmount,
                        yieldTokens[tokenIndex].reflectionsPerShareAmount,
                        block.timestamp
                    );
                }
            }
        } catch {}
    }

    function processLiquifyWeth(
        uint256 wethAmount,
        Helpers.Tax storage tax
    ) internal {
        if (wethAmount == 0) return;

        // Use the tokens that were kept in the contract for liquidity
        uint256 tokensForLiquidity = tax.amountAccumulated;
        if (tokensForLiquidity == 0) return;

        // Determine pair token: WPLS (default) or custom token from tax.tokenAddress
        address pairToken = tax.tokenAddress;
        bool useCustomPairToken = pairToken != address(0) && pairToken != wethAddress;

        uint256 pairTokenAmount = wethAmount;

        if (useCustomPairToken) {
            // Swap WPLS to the custom pair token first
            (, address swapRouter) = Helpers(helpers).getBestPair(
                wethAddress, pairToken, routers
            );
            if (swapRouter == address(0)) return;

            uint256 initialBalance = IERC20(pairToken).balanceOf(address(this));
            IERC20(wethAddress).approve(smartTrader, wethAmount);

            address[] memory path = new address[](2);
            path[0] = wethAddress;
            path[1] = pairToken;

            try SmartTrader(smartTrader).swapExactTokensForTokensSupportingFeeOnTransferTokens(
                swapRouter, address(this), wethAmount, path
            ) {
                pairTokenAmount = IERC20(pairToken).balanceOf(address(this)) - initialBalance;
            } catch {
                // Swap failed, keep tokens for next cycle
                return;
            }
        }

        // Find best router for TOKEN/pairToken (or TOKEN/WPLS) pair
        address lpPairToken = useCustomPairToken ? pairToken : wethAddress;
        (, address bestRouter) = Helpers(helpers).getBestPair(
            address(this), lpPairToken, routers
        );
        if (bestRouter == address(0)) return;

        // Approve tokens for SmartTrader
        // NOTE: must use type(uint256).max here, NOT tokensForLiquidity. SmartTrader.addLiquidity()
        // calls transferFrom(this, helper, tokensForLiquidity) which would otherwise drain the
        // allowance to zero, bricking every subsequent processAccumulatedTaxes() call (which
        // relies on the constructor's max approval set at line 1763).
        _approve(address(this), smartTrader, type(uint256).max);
        // (gas #4A) When lpPairToken is WPLS (the common case), the
        // constructor already granted smartTrader a max allowance on WPLS,
        // so this per-cycle approve is a redundant ~5K-gas SSTORE. Only run
        // it for the custom-pair-token path, where pairTokenAmount was just
        // produced by the swap above and needs a fresh allowance.
        if (useCustomPairToken) {
            IERC20(lpPairToken).approve(smartTrader, pairTokenAmount);
        }

        try SmartTrader(smartTrader).addLiquidity(
            bestRouter,
            address(this),
            lpPairToken,
            tokensForLiquidity,
            pairTokenAmount,
            deadAddress // LP tokens burned = permanent liquidity
        ) {
            taxes[tax.id].amountAccumulated = 0;
        } catch {
            // If adding liquidity fails, keep tokens for next cycle
        }
    }

    function _claimReflections(address from, address to) internal {
        if (!reflectionsEnabled) return;
        (
            uint256 fromAmount,
            uint256 toAmount,
            uint256 deployerAmount
        ) = updateAndClaimReflections(from, to, deployer);

        emit ReflectionDistributed(
            from,
            to,
            fromAmount,
            toAmount,
            deployerAmount,
            reflectionsPerShareAmount,
            block.timestamp
        );

        if (fromAmount != 0) {
            if (!isPair(from)) {
                super._transfer(address(this), from, fromAmount);
            }
        }
        if (toAmount != 0) {
            if (!isPair(to)) {
                super._transfer(address(this), to, toAmount);
            }
        }
        if (deployerAmount != 0) {
            super._transfer(address(this), deployer, deployerAmount);
        }
    }

    function initializeReflectionExclusions() internal {
        isReflectionExcluded[address(0)] = true;
        isReflectionExcluded[address(this)] = true;
        for (uint256 i; i < routers.length; ) {
            isReflectionExcluded[routers[i]] = true;
            unchecked {
                i++;
            }
        }
    }
    function isDeadAddress(address _address) internal pure returns (bool) {
        return
            _address == address(0) ||
            _address == 0x0000000000000000000000000000000000000369 ||
            _address == 0x000000000000000000000000000000000000dEaD;
    }

    function isPair(address _address) internal view returns (bool) {
        return Helpers(helpers).isPair(_address, address(this));
    }

    function isBuy(address from, address to) internal view returns (bool) {
        return Helpers(helpers).isBuy(from, to, address(this));
    }

    function isSell(address from, address to) internal view returns (bool) {
        // Pair→pair (arb bot routing) is treated as a sell so the sell-tax fires.
        if (isPair(from) && isPair(to)) return true;
        return Helpers(helpers).isSell(from, to, address(this));
    }

    /// @dev (G2) Removed the internal `getProcessingAmount(uint256)` helper —
    ///      it was dead code and was the only remaining reader of the
    ///      deprecated `currentSwapAmount` storage slot. Active swap amounts
    ///      now flow through processAccumulatedTaxes(uint256 swapAmount).

    function getTokenWETHPath(
        address tokenAddress
    ) internal view returns (address[] memory) {
        return Helpers(helpers).getTokenWPLSPath(tokenAddress);
    }

    function getWETHBuyBurnPath(
        address tokenAddress
    ) internal view returns (address[] memory) {
        return Helpers(helpers).getWPLSBuyBurnPath(tokenAddress);
    }

    function getTaxes() public view returns (Helpers.Tax[] memory) {
        return taxes;
    }

    function getFee() public view returns (uint256) {
        return ISmartTokenFactory(factory).FEE();
    }

    function getWallet() public view returns (address) {
        return ISmartTokenFactory(factory).WALLET();
    }

    // (gas #8) Factory is the live TokenFactoryTax proxy whose ABI is pinned
    // at token-deploy time, so these getters are guaranteed to exist. Drop
    // the try/catch wrapper — saves ~200-500 gas per taxed transfer.
    function getNeonLpFee() public view returns (uint256) {
        return ISmartTokenFactory(factory).NEON_LP_FEE();
    }

    function getNeonLpReceiver() public view returns (address) {
        return ISmartTokenFactory(factory).NEON_LP_RECEIVER();
    }

    function getaccumulatedFee() external view returns (uint256) {
        return accumulatedFee;
    }

    function getaccumulatedNeonFee() external view returns (uint256) {
        return accumulatedNeonFee;
    }

    function getTotalTaxs() external view returns (uint256) {
        return Helpers(helpers).getTotalTaxs(taxes);
    }

    function forceProcessAccumulatedTaxes() external onlyOwner {
        // (G2) Manual flush — pass max as the swap-budget so Helpers.getProcessingAmount
        // does not artificially cap how much accumulated tax we drain.
        processAccumulatedTaxes(type(uint256).max);
    }

    /// @notice Owner-only escape hatch: re-grant SmartTrader an unlimited
    ///         allowance over the token's self balance. The constructor sets
    ///         this to max already, so this is only needed if a future code
    ///         path drifts that allowance back down.
    function reapproveSmartTrader() external onlyOwner {
        _approve(address(this), smartTrader, type(uint256).max);
    }

    function enableTrading() external onlyOwner {
        if (tradingEnabled) revert AlreadyEnabled();
        tradingEnabled = true;
        emit TradingEnabled();
    }

    function _claimYield(address from, address to) internal {
        if (yieldEnabled) {
            updateAndClaimYield(from, to, deployer);
        }
    }

    function claimYield() external returns (bool) {
        _claimYield(msg.sender, msg.sender);
        return true;
    }

function updateTaxReceiver(uint256 taxId, address newReceiver) external onlyOwner {
        require(taxId < taxes.length, "Invalid tax ID");
        require(newReceiver != address(0), "Receiver cannot be zero address");
        taxes[taxId].receiver = newReceiver;
    }

    function updateTaxTokenAddress(uint256 taxId, address newTokenAddress) external onlyOwner {
        require(taxId < taxes.length, "Invalid tax ID");
        require(newTokenAddress != address(0), "Token address cannot be zero");
        taxes[taxId].tokenAddress = newTokenAddress;
    }

    function addTaxExclusion(address _address) external onlyOwner {
        isTaxExcluded[_address] = true;
    }

    function removeTaxExclusion(address _address) external onlyOwner {
        isTaxExcluded[_address] = false;
    }

    function inititlizeTaxExclusions() internal {
        isTaxExcluded[deployer] = true;
        isTaxExcluded[address(this)] = true;
        isTaxExcluded[smartTrader] = true;
        isTaxExcluded[factory] = true;
        //neon farms
        isTaxExcluded[0x6dDcdfce43aC44F686464dB25dEc788F034a7fbb] = true;
        isTaxExcluded[0x5dF85211Aa383994B03a52946B91329c25E622e9] = true;
        // Airdrop contract — TODO: replace with deployed address
        // isTaxExcluded[0x_AIRDROP_CONTRACT_ADDRESS_HERE] = true;
    }

    /// @notice Rescue stuck tokens — only factory owner can call
    /// @dev For when users accidentally send tokens to the token contract
    function rescueToken(address token, address to, uint256 amount) external {
        require(msg.sender == Ownable(factory).owner(), "Only factory owner");
        require(token != address(this), "Cannot rescue own token");
        IERC20(token).transfer(to, amount);
    }

    /// @notice Rescue stuck PLS — only factory owner can call
    function rescuePLS(address payable to, uint256 amount) external {
        require(msg.sender == Ownable(factory).owner(), "Only factory owner");
        (bool ok,) = to.call{value: amount}("");
        require(ok, "Transfer failed");
    }

    receive() external payable {}
}

// contracts/Tokens/TokenVesting.sol
contract TokenVesting {
    address public immutable beneficiary;
    address public immutable token;
    uint64 public immutable start;
    uint64 public immutable cliffEnd;
    uint64 public immutable vestingEnd;
    uint256 public released;

    event TokensReleased(uint256 amount);

    constructor(
        address _beneficiary,
        uint64 _cliffDuration,
        uint64 _vestingDuration,
        address _token
    ) {
        require(_beneficiary != address(0), "Zero beneficiary");
        require(_token != address(0), "Zero token");
        require(_vestingDuration > 0, "Zero vesting duration");
        require(_cliffDuration <= _vestingDuration, "Cliff > vesting");

        beneficiary = _beneficiary;
        token = _token;
        start = uint64(block.timestamp);
        cliffEnd = uint64(block.timestamp) + _cliffDuration;
        vestingEnd = uint64(block.timestamp) + _vestingDuration;
    }

    function totalAllocation() public view returns (uint256) {
        return IERC20(token).balanceOf(address(this)) + released;
    }

    function vestedAmount(uint256 timestamp) public view returns (uint256) {
        uint256 _totalAllocation = totalAllocation();
        if (timestamp < cliffEnd) {
            return 0;
        } else if (timestamp >= vestingEnd) {
            return _totalAllocation;
        } else {
            uint256 elapsed = timestamp - start;
            uint256 duration = vestingEnd - start;
            return (_totalAllocation * elapsed) / duration;
        }
    }

    function releasable() public view returns (uint256) {
        return vestedAmount(block.timestamp) - released;
    }

    function release() external {
        uint256 amount = releasable();
        require(amount > 0, "Nothing to release");
        released += amount;
        IERC20(token).transfer(beneficiary, amount);
        emit TokensReleased(amount);
    }
}

        

/

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

/// @dev Shared type declarations used by BOTH TokenTaxV2.sol (token-side) and
///      TokenFactoryTaxV2.sol (factory-side). Living in a tiny dedicated file
///      lets Solidity give them a single canonical type identity so that
///      structs passed across the factory/token boundary (e.g. `Helpers.Tax[]`
///      inside `CreateTokenParams`/`DeployTokenParams`) match cleanly.
///      Both the factory and the token's verification pages will include
///      this file, but it's pure interface/struct declarations — no
///      implementation bleeds across.

interface Helpers {
    enum TaxType {
        Burn,
        ExternalBurn,
        Dev,
        Reflection,
        Yield,
        Liquify
    }
    enum TaxMoment {
        Both,
        Buy,
        Sell
    }

    struct Tax {
        uint256 id;
        TaxType taxType;
        TaxMoment taxMoment;
        uint256 percentage;
        address receiver;
        address tokenAddress;
        address burnAddress; //not used for ExternalBurn
        bool rewardInPls; //not used for ExternalBurn
        uint256 amountAccumulated;
    }

    function getBestPair(
        address tokenA,
        address tokenB,
        address[] memory routers
    ) external view returns (address bestPair, address bestRouter);

    function isPair(
        address _address,
        address _tokenAddress
    ) external view returns (bool);

    function isBuy(
        address _from,
        address _to,
        address _tokenAddress
    ) external view returns (bool);

    function isSell(
        address _from,
        address _to,
        address _tokenAddress
    ) external view returns (bool);

    function getTokenWPLSPath(
        address tokenAddress
    ) external pure returns (address[] memory path);

    function getWPLSBuyBurnPath(
        address tokenAddress
    ) external pure returns (address[] memory path);

    function getProcessingAmount(
        uint256 accumulatedAmount,
        uint256 currentSwapAmount
    )
        external
        pure
        returns (uint256 processAmount, uint256 newAccumulatedAmount);

    function calculateTaxAmount(
        uint256 originalAmount,
        uint256 taxPercentage,
        uint256 Fee,
        bool FeeEnabled,
        uint256 globalDivider
    ) external pure returns (uint256 taxAmount, uint256 FeeAmount);

    function hasAccumulatedTaxes(
        Tax[] memory taxes
    ) external pure returns (bool);

    function getTotalTaxs(Tax[] memory taxes) external pure returns (uint256);

    function cleanPendingReflections(
        address account,
        address tokenAddress,
        uint256 reflectionsPerShareAmount,
        uint256 reflectionDebt,
        uint256 precision
    ) external view returns (uint256);

    function pendingYields(
        address account,
        address tokenAddress,
        uint256 reflectionsPerShareAmount,
        uint256 reflectionDebt,
        uint256 precision
    ) external view returns (uint256);

    function isExcludedFromTax(
        address from,
        address to,
        address SmartTrader,
        address deployer,
        address thisContract
    ) external pure returns (bool);

    function taxesInitialize(
        Helpers.Tax[] memory _taxes
    )
        external
        pure
        returns (bool, bool, bool, Helpers.Tax[] memory, address[] memory);

    function isDeadAddress(address _address) external pure returns (bool);
}

struct DeployTokenParams {
    string name_;
    string symbol_;
    address owner_;
    address mintTo;
    uint256 initialSupply;
    Helpers.Tax[] taxes;
    address smartTrader;
    address factory;
    address helpers;
    uint256 burnOnDeployPct;
    address vestingContract;
    uint256 vestAmount;
    bool tradingEnabled;
    uint64 enableTradingAt;
}
          

Compiler Settings

{"remappings":[":@1inch/solidity-utils/=lib/solidity-utils/",":@chainlink/=lib/foundry-chainlink-toolkit/",":@chainlink/contracts/=lib/foundry-chainlink-toolkit/lib/chainlink-brownie-contracts/contracts/src/",":@forge-std/=lib/forge-std/src/",":@gearbox-protocol/core-v2/=lib/core-v2/",":@gearbox-protocol/core-v3/=lib/core-v3/",":@gearbox-protocol/sdk-gov/=lib/sdk-gov/",":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",":@redstone-finance/=lib/integrations-v3/node_modules/@redstone-finance/",":@uniswap/v2-core/=lib/v2-core/",":@uniswap/v2-periphery/=lib/v2-periphery/",":chainlink-brownie-contracts/=lib/foundry-chainlink-toolkit/lib/chainlink-brownie-contracts/contracts/src/v0.6/vendor/@arbitrum/nitro-contracts/src/",":chainlink/=lib/chainlink/",":core-v2/=lib/core-v2/contracts/",":core-v3/=lib/core-v3/contracts/",":ds-test/=lib/forge-std/lib/ds-test/src/",":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",":forge-std/=lib/forge-std/src/",":foundry-chainlink-toolkit/=lib/foundry-chainlink-toolkit/",":foundry-devops/=lib/foundry-devops/",":halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",":integrations-v3/=lib/integrations-v3/",":openzeppelin-contracts copy/=lib/openzeppelin-contracts copy/",":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",":openzeppelin-contracts/=lib/openzeppelin-contracts/",":sdk-gov/=lib/sdk-gov/",":solidity-lib/=lib/solidity-lib/contracts/",":solidity-utils/=lib/solidity-utils/contracts/",":v2-core/=lib/v2-core/contracts/",":v2-periphery/=lib/v2-periphery/contracts/"],"optimizer":{"runs":1,"enabled":true},"metadata":{"bytecodeHash":"none"},"libraries":{},"evmVersion":"shanghai","compilationTarget":{"contracts/Tokens/TokenTaxV2.sol":"TokenTax"}}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"tuple","name":"p","internalType":"struct DeployTokenParams","components":[{"type":"string","name":"name_","internalType":"string"},{"type":"string","name":"symbol_","internalType":"string"},{"type":"address","name":"owner_","internalType":"address"},{"type":"address","name":"mintTo","internalType":"address"},{"type":"uint256","name":"initialSupply","internalType":"uint256"},{"type":"tuple[]","name":"taxes","internalType":"struct Helpers.Tax[]","components":[{"type":"uint256","name":"id","internalType":"uint256"},{"type":"uint8","name":"taxType","internalType":"enum Helpers.TaxType"},{"type":"uint8","name":"taxMoment","internalType":"enum Helpers.TaxMoment"},{"type":"uint256","name":"percentage","internalType":"uint256"},{"type":"address","name":"receiver","internalType":"address"},{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"address","name":"burnAddress","internalType":"address"},{"type":"bool","name":"rewardInPls","internalType":"bool"},{"type":"uint256","name":"amountAccumulated","internalType":"uint256"}]},{"type":"address","name":"smartTrader","internalType":"address"},{"type":"address","name":"factory","internalType":"address"},{"type":"address","name":"helpers","internalType":"address"},{"type":"uint256","name":"burnOnDeployPct","internalType":"uint256"},{"type":"address","name":"vestingContract","internalType":"address"},{"type":"uint256","name":"vestAmount","internalType":"uint256"},{"type":"bool","name":"tradingEnabled","internalType":"bool"},{"type":"uint64","name":"enableTradingAt","internalType":"uint64"}]}]},{"type":"error","name":"AlreadyEnabled","inputs":[]},{"type":"error","name":"ERC20InsufficientAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"allowance","internalType":"uint256"},{"type":"uint256","name":"needed","internalType":"uint256"}]},{"type":"error","name":"ERC20InsufficientBalance","inputs":[{"type":"address","name":"sender","internalType":"address"},{"type":"uint256","name":"balance","internalType":"uint256"},{"type":"uint256","name":"needed","internalType":"uint256"}]},{"type":"error","name":"ERC20InvalidApprover","inputs":[{"type":"address","name":"approver","internalType":"address"}]},{"type":"error","name":"ERC20InvalidReceiver","inputs":[{"type":"address","name":"receiver","internalType":"address"}]},{"type":"error","name":"ERC20InvalidSender","inputs":[{"type":"address","name":"sender","internalType":"address"}]},{"type":"error","name":"ERC20InvalidSpender","inputs":[{"type":"address","name":"spender","internalType":"address"}]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"error","name":"TradingDisabled","inputs":[]},{"type":"error","name":"ZeroTaxPercentage","inputs":[]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"BurnTaxProcessed","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ExternalBurnProcessed","inputs":[{"type":"uint256","name":"tokenAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"taxid","internalType":"uint256","indexed":false},{"type":"uint256","name":"wethAmount","internalType":"uint256","indexed":false},{"type":"address","name":"receiver","internalType":"address","indexed":false},{"type":"address","name":"tokenToBurn","internalType":"address","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"ReflectionDistributed","inputs":[{"type":"address","name":"from","internalType":"address","indexed":false},{"type":"address","name":"to","internalType":"address","indexed":false},{"type":"uint256","name":"fromAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"toAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"deployerAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"reflectionsPerShareAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ReflectionTaxProcessed","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"newReflectionsPerShareAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TaxCollected","inputs":[{"type":"uint256","name":"taxId","internalType":"uint256","indexed":true},{"type":"uint8","name":"taxType","internalType":"enum Helpers.TaxType","indexed":false},{"type":"uint8","name":"taxMoment","internalType":"enum Helpers.TaxMoment","indexed":false},{"type":"address","name":"from","internalType":"address","indexed":false},{"type":"address","name":"to","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TradingEnabled","inputs":[],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"YieldDistributed","inputs":[{"type":"address","name":"tokenAddress","internalType":"address","indexed":false},{"type":"address","name":"recipient","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"reflectionsPerShareAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"YieldTaxProcessed","inputs":[{"type":"uint256","name":"tokenAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"wethAmount","internalType":"uint256","indexed":false},{"type":"address","name":"yieldTokenAddress","internalType":"address","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"noRouter","inputs":[],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addTaxExclusion","inputs":[{"type":"address","name":"_address","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"burn","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"claimYield","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enableTrading","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"enableTradingAt","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"forceProcessAccumulatedTaxes","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCurrentReflectionsPerShareAmount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getNeonLpFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getNeonLpReceiver","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct Helpers.Tax[]","components":[{"type":"uint256","name":"id","internalType":"uint256"},{"type":"uint8","name":"taxType","internalType":"enum Helpers.TaxType"},{"type":"uint8","name":"taxMoment","internalType":"enum Helpers.TaxMoment"},{"type":"uint256","name":"percentage","internalType":"uint256"},{"type":"address","name":"receiver","internalType":"address"},{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"address","name":"burnAddress","internalType":"address"},{"type":"bool","name":"rewardInPls","internalType":"bool"},{"type":"uint256","name":"amountAccumulated","internalType":"uint256"}]}],"name":"getTaxes","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTotalTaxs","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getWallet","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getYieldTokenReflectionDebts","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct Manager.YieldToken[]","components":[{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"uint256","name":"reflectionsPerShareAmount","internalType":"uint256"}]}],"name":"getYieldTokens","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getaccumulatedFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getaccumulatedNeonFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"initialSupply","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isExcludedFromReflections","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isReflectionExcluded","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pendingReflections","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pendingYields","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"uint256","name":"tokenIndex","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"reapproveSmartTrader","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeTaxExclusion","inputs":[{"type":"address","name":"_address","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"rescuePLS","inputs":[{"type":"address","name":"to","internalType":"address payable"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"rescueToken","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"id","internalType":"uint256"},{"type":"uint8","name":"taxType","internalType":"enum Helpers.TaxType"},{"type":"uint8","name":"taxMoment","internalType":"enum Helpers.TaxMoment"},{"type":"uint256","name":"percentage","internalType":"uint256"},{"type":"address","name":"receiver","internalType":"address"},{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"address","name":"burnAddress","internalType":"address"},{"type":"bool","name":"rewardInPls","internalType":"bool"},{"type":"uint256","name":"amountAccumulated","internalType":"uint256"}],"name":"taxes","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalBurned","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalLiquify","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalReflection","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupport","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalYield","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"tradingEnabled","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateTaxReceiver","inputs":[{"type":"uint256","name":"taxId","internalType":"uint256"},{"type":"address","name":"newReceiver","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateTaxTokenAddress","inputs":[{"type":"uint256","name":"taxId","internalType":"uint256"},{"type":"address","name":"newTokenAddress","internalType":"address"}]},{"type":"receive","stateMutability":"payable"}]
              

Contract Creation Code

Verify & Publish
0x6101006040527398bf93ebf5c380c0e6ae8e192a7e2ae08edacc02608090815273165c3410fc91ef562c50559f7d2289febed552d960a05273cc73b59f8d7b7c532703bdfea2808a28a488cf4760c05273eb45a3c4aedd0f47f345fb4c8a1802bb5740d72560e052610075906012906004611018565b50348015610081575f5ffd5b506040516165ff3803806165ff8339810160408190526100a091611313565b60408101518151602083015160036100b88382611505565b5060046100c58282611505565b5050506001600160a01b0381166100fa575f604051631e4fbdf760e01b81526004016100f191906115bf565b60405180910390fd5b61010381610421565b50610180810151600f80546101a08401516001600160401b031661010002610100600160481b0319931515939093166001600160481b031990911617919091179055606081015160808201516101599190610472565b6101208101511561019f575f612710826101200151836080015161017d91906115e7565b61018791906115fe565b905061019d8260600151826104aa60201b60201c565b505b5f8161016001511180156101c057506101408101516001600160a01b031615155b156101e4576101e481606001518261014001518361016001516104de60201b60201c565b6060810151601080546001600160a01b039283166001600160a01b0319918216179091556080830151600e5560c0830151600f8054918416690100000000000000000002600160481b600160e81b031990921691909117905560e08301516011805491909316911617905560a081015161025d90610540565b6103376010546001600160a01b039081165f908152601360205260408082208054600160ff1991821681179092553084528284208054821683179055600f5469010000000000000000009004851684528284208054821683179055601154909416835290822080548416821790557f57cf93e0db3e0da914216c2f0e12ee44cd857ba192417d87569e725c63b18eab8054841682179055735df85211aa383994b03a52946b91329c25e622e99091527f77941af77031539170e7eb298cf7e6530caa0379750b8de97db66d0a13c808cc8054909216179055565b601754610100900460ff1680610355575060175462010000900460ff165b1561036257610362610c6b565b600f5460405163095ea7b360e01b815269010000000000000000009091046001600160a01b031660048201525f19602482015273a1077a294dde1b09bb078844df40758a5d0f9a279063095ea7b3906044016020604051808303815f875af11580156103d0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103f4919061161d565b50600f5461041b903090690100000000000000000090046001600160a01b03165f19610d14565b5061168b565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6001600160a01b03821661049b575f60405163ec442f0560e01b81526004016100f191906115bf565b6104a65f8383610d21565b5050565b6001600160a01b0382166104d3575f604051634b637e8f60e11b81526004016100f191906115bf565b6104a6825f83610d21565b6001600160a01b038316610507575f604051634b637e8f60e11b81526004016100f191906115bf565b6001600160a01b038216610530575f60405163ec442f0560e01b81526004016100f191906115bf565b61053b838383610d21565b505050565b5f5f5b8251811015610c185760188382815181106105605761056061163d565b6020908102919091018101518254600181810185555f94855293839020825160079092020190815591810151828401805492949192909160ff19909116908360058111156105b0576105b0611651565b0217905550604082015160018201805461ff0019166101008360028111156105da576105da611651565b02179055506060820151600282015560808201516003820180546001600160a01b039283166001600160a01b03199182161790915560a08401516004840180549184169190921617905560c083015160058301805460e08601511515600160a01b026001600160a81b0319909116929093169190911791909117905561010090910151600690910155601880548291908290811061067a5761067a61163d565b905f5260205f2090600702015f018190555082818151811061069e5761069e61163d565b6020026020010151606001515f036106c957604051632e3d979b60e21b815260040160405180910390fd5b6113888382815181106106de576106de61163d565b60200260200101516060015111156107385760405162461bcd60e51b815260206004820152601760248201527f5461782070657263656e7461676520746f6f206869676800000000000000000060448201526064016100f1565b5f83828151811061074b5761074b61163d565b602002602001015160400151600281111561076857610768611651565b036107a85782818151811061077f5761077f61163d565b602002602001015160600151600261079791906115e7565b6107a19083611665565b91506107d4565b8281815181106107ba576107ba61163d565b602002602001015160600151826107d19190611665565b91505b60038382815181106107e8576107e861163d565b602002602001015160200151600581111561080557610805611651565b0361081a576017805461ff0019166101001790555b600483828151811061082e5761082e61163d565b602002602001015160200151600581111561084b5761084b611651565b036108bf576017805462ff000019166201000017905582515f908490839081106108775761087761163d565b602002602001015160a001516001600160a01b0316146108bf576108bd8382815181106108a6576108a661163d565b602002602001015160a00151610e4760201b60201c565b505b60018382815181106108d3576108d361163d565b60200260200101516020015160058111156108f0576108f0611651565b03610a23575f6001600160a01b03168382815181106109115761091161163d565b6020026020010151608001516001600160a01b0316036109815760405162461bcd60e51b815260206004820152602560248201527f45787465726e616c4275726e3a2072656365697665722063616e6e6f74206265604482015264207a65726f60d81b60648201526084016100f1565b5f6001600160a01b031683828151811061099d5761099d61163d565b602002602001015160a001516001600160a01b031603610a115760405162461bcd60e51b815260206004820152602960248201527f45787465726e616c4275726e3a20746f6b656e416464726573732063616e6e6f60448201526874206265207a65726f60b81b60648201526084016100f1565b6017805460ff19166001179055610c10565b6002838281518110610a3757610a3761163d565b6020026020010151602001516005811115610a5457610a54611651565b03610b0d575f6001600160a01b0316838281518110610a7557610a7561163d565b6020026020010151608001516001600160a01b031603610ad75760405162461bcd60e51b815260206004820152601c60248201527f4465763a2072656365697665722063616e6e6f74206265207a65726f0000000060448201526064016100f1565b828181518110610ae957610ae961163d565b602002602001015160e0015115610b08576017805460ff191660011790555b610c10565b6004838281518110610b2157610b2161163d565b6020026020010151602001516005811115610b3e57610b3e611651565b03610bcc575f6001600160a01b0316838281518110610b5f57610b5f61163d565b602002602001015160a001516001600160a01b031603610a115760405162461bcd60e51b815260206004820152602260248201527f5969656c643a20746f6b656e416464726573732063616e6e6f74206265207a65604482015261726f60f01b60648201526084016100f1565b6005838281518110610be057610be061163d565b6020026020010151602001516005811115610bfd57610bfd611651565b03610c10576017805460ff191660011790555b600101610543565b50611f408111156104a65760405162461bcd60e51b815260206004820152601d60248201527f546f74616c207461782070657263656e7461676520746f6f206869676800000060448201526064016100f1565b600a6020527f13da86008ba1c6922daee3e07db95305ef49ebced9f5467a0b8613fcc6b343e38054600160ff199182168117909255305f90815260408120805490921690921790555b601254811015610d11576001600a5f60128481548110610cd657610cd661163d565b5f918252602080832091909101546001600160a01b031683528201929092526040019020805460ff1916911515919091179055600101610cb4565b50565b61053b8383836001610f45565b6001600160a01b038316610d4b578060025f828254610d409190611665565b90915550610dbb9050565b6001600160a01b0383165f9081526020819052604090205481811015610d9d5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016100f1565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216610dd757600280548290039055610df5565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610e3a91815260200190565b60405180910390a3505050565b5f805b600654811015610e9d57826001600160a01b031660068281548110610e7157610e7161163d565b5f9182526020909120600290910201546001600160a01b031603610e955792915050565b600101610e4a565b50604080518082019091526001600160a01b0383811682525f6020830181815260068054600180820183559382905294517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f600290960295860180546001600160a01b0319169190951617909355517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d409093019290925554610f3f9190611678565b92915050565b6001600160a01b038416610f6e575f60405163e602df0560e01b81526004016100f191906115bf565b6001600160a01b038316610f97575f604051634a1406b160e11b81526004016100f191906115bf565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561101257826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161100991815260200190565b60405180910390a35b50505050565b828054828255905f5260205f2090810192821561106b579160200282015b8281111561106b57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190611036565b5061107792915061107b565b5090565b5b80821115611077575f815560010161107c565b634e487b7160e01b5f52604160045260245ffd5b60405161012081016001600160401b03811182821017156110c6576110c661108f565b60405290565b6040516101c081016001600160401b03811182821017156110c6576110c661108f565b604051601f8201601f191681016001600160401b03811182821017156111175761111761108f565b604052919050565b5f82601f83011261112e575f5ffd5b81516001600160401b038111156111475761114761108f565b61115a601f8201601f19166020016110ef565b81815284602083860101111561116e575f5ffd5b5f5b8281101561118c57602081860181015183830182015201611170565b505f918101602001919091529392505050565b80516001600160a01b03811681146111b5575f5ffd5b919050565b8051600681106111b5575f5ffd5b8051600381106111b5575f5ffd5b805180151581146111b5575f5ffd5b5f82601f8301126111f4575f5ffd5b81516001600160401b0381111561120d5761120d61108f565b61121c60208260051b016110ef565b808282526020820191506020610120840286010192508583111561123e575f5ffd5b602085015b838110156112f357610120818803121561125b575f5ffd5b6112636110a3565b81518152611273602083016111ba565b6020820152611284604083016111c8565b60408201526060828101519082015261129f6080830161119f565b60808201526112b060a0830161119f565b60a08201526112c160c0830161119f565b60c08201526112d260e083016111d6565b60e08201526101008281015190820152835260209092019161012001611243565b5095945050505050565b80516001600160401b03811681146111b5575f5ffd5b5f60208284031215611323575f5ffd5b81516001600160401b03811115611338575f5ffd5b82016101c0818503121561134a575f5ffd5b6113526110cc565b81516001600160401b03811115611367575f5ffd5b6113738682850161111f565b82525060208201516001600160401b0381111561138e575f5ffd5b61139a8682850161111f565b6020830152506113ac6040830161119f565b60408201526113bd6060830161119f565b60608201526080828101519082015260a08201516001600160401b038111156113e4575f5ffd5b6113f0868285016111e5565b60a08301525061140260c0830161119f565b60c082015261141360e0830161119f565b60e0820152611425610100830161119f565b6101008201526101208281015190820152611443610140830161119f565b610140820152610160828101519082015261146161018083016111d6565b6101808201526114746101a083016112fd565b6101a0820152949350505050565b600181811c9082168061149657607f821691505b6020821081036114b457634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561053b57805f5260205f20601f840160051c810160208510156114df5750805b601f840160051c820191505b818110156114fe575f81556001016114eb565b5050505050565b81516001600160401b0381111561151e5761151e61108f565b6115328161152c8454611482565b846114ba565b6020601f821160018114611564575f831561154d5750848201515b5f19600385901b1c1916600184901b1784556114fe565b5f84815260208120601f198516915b828110156115935787850151825560209485019460019092019101611573565b50848210156115b057868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b6001600160a01b0391909116815260200190565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610f3f57610f3f6115d3565b5f8261161857634e487b7160e01b5f52601260045260245ffd5b500490565b5f6020828403121561162d575f5ffd5b611636826111d6565b9392505050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b80820180821115610f3f57610f3f6115d3565b81810381811115610f3f57610f3f6115d3565b614f67806116985f395ff3fe60806040526004361061021a575f3560e01c8063014182051461022557806306fdde031461024d578063095ea7b31461026e5780630d3ebcbf1461029d57806313299604146102b3578063138dd4d1146102d457806318160ddd146102e857806322849720146102fc57806323b872dd146103115780632973ef2d14610330578063313ce56714610351578063346847b41461036c578063378dc3dc14610380578063406cf2291461039557806342966c68146103a95780634ada218b146103c85780634f30800d146103e157806358232c94146103f5578063695d69b3146104145780636a2072d414610433578063709df63c1461045f57806370a0823114610480578063715018a61461049f5780637922fc01146104b35780637c8b6f09146104c857806384527bbd146105045780638453ef99146105195780638a8c523c1461052d5780638da5cb5b146105415780639045be581461055557806390b8e5981461058357806395d89b41146105a25780639b165f4e146105b6578063a9059cbb146105d5578063ad826ab6146105f4578063b2ff197314610613578063c5be2bc714610627578063cb78c1631461065b578063ce7b63ed1461066f578063ced72f8714610683578063d89135cd14610697578063dd62ed3e146106ac578063e4f8d62e146106cb578063e5711e8b146106ea578063e6375d3e14610709578063eb50c06114610728578063f2fde38b14610747575f5ffd5b3661022157005b5f5ffd5b348015610230575f5ffd5b5061023a601c5481565b6040519081526020015b60405180910390f35b348015610258575f5ffd5b50610261610766565b604051610244919061455f565b348015610279575f5ffd5b5061028d6102883660046145be565b6107f6565b6040519015158152602001610244565b3480156102a8575f5ffd5b506102b161080f565b005b3480156102be575f5ffd5b506102c7610839565b60405161024491906145f5565b3480156102df575f5ffd5b506102c76108a9565b3480156102f3575f5ffd5b5060025461023a565b348015610307575f5ffd5b5061023a601b5481565b34801561031c575f5ffd5b5061028d61032b366004614609565b6108f0565b34801561033b575f5ffd5b50610344610913565b604051610244919061467f565b34801561035c575f5ffd5b5060405160128152602001610244565b348015610377575f5ffd5b5061023a610a42565b34801561038b575f5ffd5b5061023a600e5481565b3480156103a0575f5ffd5b5061028d610aad565b3480156103b4575f5ffd5b506102b16103c336600461474d565b610abe565b3480156103d3575f5ffd5b50600f5461028d9060ff1681565b3480156103ec575f5ffd5b5060075461023a565b348015610400575f5ffd5b506102b161040f366004614764565b610b08565b34801561041f575f5ffd5b5061023a61042e366004614792565b610bd9565b34801561043e575f5ffd5b5061045261044d366004614792565b610bf8565b60405161024491906147ad565b34801561046a575f5ffd5b50610473610c61565b60405161024491906147e4565b34801561048b575f5ffd5b5061023a61049a366004614792565b610ccb565b3480156104aa575f5ffd5b506102b1610ce5565b3480156104be575f5ffd5b5061023a601d5481565b3480156104d3575f5ffd5b50600f546104ec9061010090046001600160401b031681565b6040516001600160401b039091168152602001610244565b34801561050f575f5ffd5b5061023a601a5481565b348015610524575f5ffd5b506102b1610cf6565b348015610538575f5ffd5b506102b1610d08565b34801561054c575f5ffd5b506102c7610d58565b348015610560575f5ffd5b5061028d61056f366004614792565b600a6020525f908152604090205460ff1681565b34801561058e575f5ffd5b506102b161059d3660046145be565b610d67565b3480156105ad575f5ffd5b50610261610ea1565b3480156105c1575f5ffd5b506102b16105d0366004614792565b610eb0565b3480156105e0575f5ffd5b5061028d6105ef3660046145be565b610edb565b3480156105ff575f5ffd5b506102b161060e366004614764565b610ee8565b34801561061e575f5ffd5b5060165461023a565b348015610632575f5ffd5b5061064661064136600461474d565b610fb1565b60405161024499989796959493929190614830565b348015610666575f5ffd5b5061023a611026565b34801561067a575f5ffd5b5060155461023a565b34801561068e575f5ffd5b5061023a611073565b3480156106a2575f5ffd5b5061023a60195481565b3480156106b7575f5ffd5b5061023a6106c636600461488f565b6110ba565b3480156106d6575f5ffd5b5061023a6106e53660046145be565b6110e4565b3480156106f5575f5ffd5b506102b1610704366004614609565b6111fa565b348015610714575f5ffd5b5061028d610723366004614792565b611364565b348015610733575f5ffd5b506102b1610742366004614792565b611381565b348015610752575f5ffd5b506102b1610761366004614792565b6113a9565b606060038054610775906148bb565b80601f01602080910402602001604051908101604052809291908181526020018280546107a1906148bb565b80156107ec5780601f106107c3576101008083540402835291602001916107ec565b820191905f5260205f20905b8154815290600101906020018083116107cf57829003601f168201915b5050505050905090565b5f336108038185856113e3565b60019150505b92915050565b6108176113f0565b600f54610837903090600160481b90046001600160a01b03165f196113e3565b565b601154604080516336ce6de360e11b815290515f926001600160a01b031691636d9cdbc69160048083019260209291908290030181865afa158015610880573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108a49190614903565b905090565b60115460408051637bb8996d60e01b815290515f926001600160a01b031691637bb8996d9160048083019260209291908290030181865afa158015610880573d5f5f3e3d5ffd5b5f336108fd858285611422565b61090885858561146d565b506001949350505050565b60606018805480602002602001604051908101604052809291908181526020015f905b82821015610a39578382905f5260205f209060070201604051806101200160405290815f8201548152602001600182015f9054906101000a900460ff16600581111561098457610984614647565b600581111561099557610995614647565b81526020016001820160019054906101000a900460ff1660028111156109bd576109bd614647565b60028111156109ce576109ce614647565b8152600282015460208083019190915260038301546001600160a01b03908116604084015260048401548116606084015260058401549081166080840152600160a01b900460ff16151560a083015260069092015460c0909101529082526001929092019101610936565b50505050905090565b6011546040805163b5a08dd160e01b815290515f926001600160a01b03169163b5a08dd19160048083019260209291908290030181865afa158015610a89573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108a4919061491e565b5f610ab833336116f1565b50600190565b8060195f828254610acf9190614949565b90915550506040515f516020614e9b5f395f51905f5290610af3908390429061495c565b60405180910390a1610b05338261171f565b50565b610b106113f0565b6018548210610b3a5760405162461bcd60e51b8152600401610b319061496a565b60405180910390fd5b6001600160a01b038116610b8f5760405162461bcd60e51b815260206004820152601c60248201527b546f6b656e20616464726573732063616e6e6f74206265207a65726f60201b6044820152606401610b31565b8060188381548110610ba357610ba3614992565b905f5260205f2090600702016004015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b5f610be382611364565b15610bef57505f919050565b61080982611753565b6001600160a01b0381165f908152600c6020908152604091829020805483518184028101840190945280845260609392830182828015610c5557602002820191905f5260205f20905b815481526020019060010190808311610c41575b50505050509050919050565b60606006805480602002602001604051908101604052809291908181526020015f905b82821015610a39575f848152602090819020604080518082019091526002850290910180546001600160a01b03168252600190810154828401529083529092019101610c84565b6001600160a01b03165f9081526020819052604090205490565b610ced6113f0565b6108375f6117f0565b610cfe6113f0565b6108375f19611841565b610d106113f0565b600f5460ff1615610d3457604051637952fbad60e11b815260040160405180910390fd5b600f805460ff191660011790556040515f516020614efb5f395f51905f52905f90a1565b6005546001600160a01b031690565b60115f9054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610db7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ddb9190614903565b6001600160a01b0316336001600160a01b031614610e0b5760405162461bcd60e51b8152600401610b31906149a6565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114610e54576040519150601f19603f3d011682016040523d82523d5f602084013e610e59565b606091505b5050905080610e9c5760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606401610b31565b505050565b606060048054610775906148bb565b610eb86113f0565b6001600160a01b03165f908152601360205260409020805460ff19166001179055565b5f3361080381858561146d565b610ef06113f0565b6018548210610f115760405162461bcd60e51b8152600401610b319061496a565b6001600160a01b038116610f675760405162461bcd60e51b815260206004820152601f60248201527f52656365697665722063616e6e6f74206265207a65726f2061646472657373006044820152606401610b31565b8060188381548110610f7b57610f7b614992565b905f5260205f2090600702016003015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b60188181548110610fc0575f80fd5b5f918252602090912060079091020180546001820154600283015460038401546004850154600586015460069096015494965060ff8085169661010090950481169593946001600160a01b039384169492841693811692600160a01b9091049091169089565b604051625f8d8f60e81b81525f905f516020614ebb5f395f51905f5290635f8d8f0090611058906018906004016149de565b602060405180830381865afa158015610a89573d5f5f3e3d5ffd5b6011546040805163c57981b560e01b815290515f926001600160a01b03169163c57981b59160048083019260209291908290030181865afa158015610a89573d5f5f3e3d5ffd5b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6001600160a01b0382165f908152600c6020526040812054821061110957505f610809565b5f516020614ebb5f395f51905f526001600160a01b031663a89055e584306006868154811061113a5761113a614992565b905f5260205f20906002020160010154600c5f896001600160a01b03166001600160a01b031681526020019081526020015f20878154811061117e5761117e614992565b905f5260205f2001546b204fce5e3e250261100000006040518663ffffffff1660e01b81526004016111b4959493929190614abf565b602060405180830381865afa1580156111cf573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111f3919061491e565b9392505050565b60115f9054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561124a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061126e9190614903565b6001600160a01b0316336001600160a01b03161461129e5760405162461bcd60e51b8152600401610b31906149a6565b306001600160a01b038416036112f05760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103932b9b1bab29037bbb7103a37b5b2b760491b6044820152606401610b31565b60405163a9059cbb60e01b81526001600160a01b0384169063a9059cbb9061131e9085908590600401614af0565b6020604051808303815f875af115801561133a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061135e9190614b09565b50505050565b6001600160a01b03165f908152600a602052604090205460ff1690565b6113896113f0565b6001600160a01b03165f908152601360205260409020805460ff19169055565b6113b16113f0565b6001600160a01b0381166113da575f604051631e4fbdf760e01b8152600401610b3191906145f5565b610b05816117f0565b610e9c8383836001612322565b336113f9610d58565b6001600160a01b031614610837573360405163118cdaa760e01b8152600401610b3191906145f5565b5f61142d84846110ba565b90505f1981101561135e578181101561145f57828183604051637dc7a0d960e11b8152600401610b3193929190614b28565b61135e84848484035f612322565b6017805460ff60201b19169055600f546001600160a01b0384165f9081526013602052604090205460ff9182169116811580156114b95750600f5461010090046001600160401b031615155b80156114d55750600f5461010090046001600160401b03164210155b1561150357600f805460ff191660019081179091556040519092505f516020614efb5f395f51905f52905f90a15b61150c846123f4565b156115225761151b858461171f565b5050505050565b8115801561152e575080155b1561154c5760405163bcb8b8fb60e01b815260040160405180910390fd5b5f6115568561242c565b601854909150158061157257506017546301000000900460ff16155b8061157a5750815b8061159c57506001600160a01b0385165f9081526013602052604090205460ff165b806115a95750600d5460ff165b156115fb576017546301000000900460ff161580156115c55750805b156115de576017805463ff000000191663010000001790555b6115e886866116f1565b6115f38686866124a7565b505050505050565b80801561162057506001600160a01b0385165f908152600a602052604090205460ff16155b15611648576001600160a01b0385165f908152600a60205260409020805460ff191660011790555b5f6116538787612504565b90505f8161166a576116658888612579565b61166c565b5f5b90505f61167c89898986866125d4565b60175490915060ff16801561169b5750601754600160201b900460ff16155b80156116a5575082155b156116c7576116b387611841565b6017805460ff60201b1916600160201b1790555b6116d189896116f1565b6116db898961289c565b6116e68989836124a7565b505050505050505050565b60175462010000900460ff161561171b5760105461171b90839083906001600160a01b031661299a565b5050565b6001600160a01b038216611748575f604051634b637e8f60e11b8152600401610b3191906145f5565b61171b825f83612e51565b6007546001600160a01b0382165f90815260096020526040808220549051631d2fa43b60e11b815291925f516020614ebb5f395f51905f5292633a5f4876926117b19287923092906b204fce5e3e2502611000000090600401614abf565b602060405180830381865afa1580156117cc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610809919061491e565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b600d805460ff191660011790556018545f90819081816001600160401b0381111561186e5761186e614b49565b604051908082528060200260200182016040528015611897578160200160208202803683370190505b5090505f826001600160401b038111156118b3576118b3614b49565b6040519080825280602002602001820160405280156118dc578160200160208202803683370190505b5090505f5b83811015611b44575f601882815481106118fd576118fd614992565b905f5260205f209060070201905080600601545f0361191c5750611b3c565b60018082015460ff16600581111561193657611936614647565b148061197057506002600182015460ff16600581111561195857611958614647565b14801561197057506005810154600160a01b900460ff165b8061199357506004600182015460ff16600581111561199157611991614647565b145b806119b657506005600182015460ff1660058111156119b4576119b4614647565b145b15611b3a57600681015460405163059b6d4760e21b81525f9182915f516020614ebb5f395f51905f529163166db51c916119f591908e9060040161495c565b6040805180830381865afa158015611a0f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a339190614b5d565b90925090508115611b0f5781816005600186015460ff166005811115611a5b57611a5b614647565b03611a8457611a6b600285614b7f565b9150611a778285614b9e565b611a819084614949565b90505b6001888781518110611a9857611a98614992565b60200260200101901515908115158152505081878781518110611abd57611abd614992565b6020908102919091010152611ad2828c614949565b9a5089611ade81614bb1565b9a50508060188781548110611af557611af5614992565b905f5260205f209060070201600601819055505050611b37565b8060188581548110611b2357611b23614992565b905f5260205f209060070201600601819055505b50505b505b6001016118e1565b50604051632a8ddb2f60e01b81525f905f516020614ebb5f395f51905f5290632a8ddb2f90611b899030905f516020614f1b5f395f51905f5290601290600401614bc9565b6040805180830381865afa158015611ba3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bc79190614c35565b9150506001600160a01b038116611c0b576040517f34be9cb68ddf4eeebba29ea0e1db420286ea39e4ce7a377e66a7b47a998a6d03905f90a1505050505050612315565b5f5f5f5f5f516020614ebb5f395f51905f526001600160a01b031663166db51c6015548d6040518363ffffffff1660e01b8152600401611c4c92919061495c565b6040805180830381865afa158015611c66573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c8a9190614b5d565b60165460405163059b6d4760e21b81529296509093505f516020614ebb5f395f51905f529163166db51c91611cc3918f9060040161495c565b6040805180830381865afa158015611cdd573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d019190614b5d565b601593909355601692909255509050611d1a8289614949565b9750611d268189614949565b9750875f03611d3c575050505050505050612315565b600f54600160481b90046001600160a01b0316637e18437984308b611d6082612f64565b6040518563ffffffff1660e01b8152600401611d7f9493929190614c62565b5f604051808303815f87803b158015611d96575f5ffd5b505af1925050508015611da7575060015b611e69575f5b86811015611e2c57858181518110611dc757611dc7614992565b602002602001015115611e2457848181518110611de657611de6614992565b602002602001015160188281548110611e0157611e01614992565b905f5260205f2090600702016006015f828254611e1e9190614949565b90915550505b600101611dad565b508160155f828254611e3e9190614949565b925050819055508060165f828254611e569190614949565b9091555061231598505050505050505050565b6008546040516370a0823160e01b81525f91905f516020614f1b5f395f51905f52906370a0823190611e9f9030906004016145f5565b602060405180830381865afa158015611eba573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ede919061491e565b611ee89190614b9e565b9050611ef68184848c612fd8565b611f009082614b9e565b9050611f0c838a614b9e565b9850611f18828a614b9e565b9850805f03611f2f57505050505050505050612315565b5f5b8781101561230a57868181518110611f4b57611f4b614992565b60200260200101511580611f775750858181518110611f6c57611f6c614992565b60200260200101515f145b612302575f8a83888481518110611f9057611f90614992565b6020026020010151611fa29190614cd3565b611fac9190614b7f565b90505f60188381548110611fc257611fc2614992565b5f9182526020909120600790910201905060018082015460ff166005811115611fed57611fed614647565b03612133575f516020614e7b5f395f51905f5288848151811061201257612012614992565b602090810291909101015182546003840154600485015460405161204a94939288926001600160a01b03918216929116904290614cea565b60405180910390a160408051610120810190915281548152600182015461212e9184918490602083019060ff16600581111561208857612088614647565b600581111561209957612099614647565b81526020016001820160019054906101000a900460ff1660028111156120c1576120c1614647565b60028111156120d2576120d2614647565b81526002820154602082015260038201546001600160a01b03908116604083015260048301548116606083015260058301549081166080830152600160a01b900460ff16151560a082015260069091015460c090910152613061565b6122ff565b6002600182015460ff16600581111561214e5761214e614647565b14801561216657506005810154600160a01b900460ff165b1561218457600381015461212e9083906001600160a01b031661324e565b6004600182015460ff16600581111561219f5761219f614647565b036122d5575f516020614edb5f395f51905f528884815181106121c4576121c4614992565b602090810291909101015160048301546040516121f1929186916001600160a01b03909116904290614d1e565b60405180910390a160408051610120810190915281548152600182015461212e9184918490602083019060ff16600581111561222f5761222f614647565b600581111561224057612240614647565b81526020016001820160019054906101000a900460ff16600281111561226857612268614647565b600281111561227957612279614647565b81526002820154602082015260038201546001600160a01b03908116604083015260048301548116606083015260058301549081166080830152600160a01b900460ff16151560a082015260069091015460c09091015261336c565b6005600182015460ff1660058111156122f0576122f0614647565b036122ff576122ff828261377d565b50505b600101611f31565b505050505050505050505b50600d805460ff19169055565b6001600160a01b03841661234b575f60405163e602df0560e01b8152600401610b3191906145f5565b6001600160a01b038316612374575f604051634a1406b160e11b8152600401610b3191906145f5565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561135e57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516123e691815260200190565b60405180910390a350505050565b5f6001600160a01b038216158061241557506103696001600160a01b038316145b806108095750506001600160a01b031661dead1490565b604051630d5c7b5d60e41b81526001600160a01b03821660048201523060248201525f905f516020614ebb5f395f51905f529063d5c7b5d090604401602060405180830381865afa158015612483573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108099190614b09565b6001600160a01b0383166124d0575f604051634b637e8f60e11b8152600401610b3191906145f5565b6001600160a01b0382166124f9575f60405163ec442f0560e01b8152600401610b3191906145f5565b610e9c838383612e51565b604051636468b51760e01b81525f905f516020614ebb5f395f51905f5290636468b5179061253a90869086903090600401614d42565b602060405180830381865afa158015612555573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111f39190614b09565b5f6125838361242c565b801561259357506125938261242c565b156125a057506001610809565b60405163154b004960e31b81525f516020614ebb5f395f51905f529063aa5802489061253a90869086903090600401614d42565b6040805160e0810182525f60a0820181905260c082018190526001600160a01b03888116835287166020830152918101859052831515606082015282151560808201526017548291829182919060ff16801561264057505f6126346108a9565b6001600160a01b031614155b156126535761264d610a42565b60a08201525b61265b611073565b60c082015260188054604080516020808402820181019092528281525f9390929091849084015b82821015612785578382905f5260205f209060070201604051806101200160405290815f8201548152602001600182015f9054906101000a900460ff1660058111156126d0576126d0614647565b60058111156126e1576126e1614647565b81526020016001820160019054906101000a900460ff16600281111561270957612709614647565b600281111561271a5761271a614647565b8152600282015460208083019190915260038301546001600160a01b03908116604084015260048401548116606084015260058401549081166080840152600160a01b900460ff16151560a083015260069092015460c0909101529082526001929092019101612682565b505082519293505f9150505b818110156127f9575f5f5f6127bf878786815181106127b2576127b2614992565b6020026020010151613ce9565b919450925090506127d0838b614949565b99506127dc828a614949565b98506127e88189614949565b975050600190920191506127919050565b5084156128445760175460ff1615612832576128168c30876124a7565b8460155f8282546128279190614949565b909155506128449050565b6128448c61283e610839565b876124a7565b831561286c576128558c30866124a7565b8360165f8282546128669190614949565b90915550505b8385612878888d614b9e565b6128829190614b9e565b61288c9190614b9e565b9c9b505050505050505050505050565b601754610100900460ff166128af575050565b6010545f90819081906128ce90869086906001600160a01b0316613e23565b600754604080516001600160a01b03808c1682528a166020820152908101859052606081018490526080810183905260a08101919091524260c082015292955090935091507f7f2255e92a9403cf8dd4b9f679ad1f5f5ce9226dd19b0faf14c84bace34d235b9060e00160405180910390a1821561295e5761294f8561242c565b61295e5761295e3086856124a7565b811561297c5761296d8461242c565b61297c5761297c3085846124a7565b801561151b5760105461151b9030906001600160a01b0316836124a7565b5f5b60065481101561135e575b6001600160a01b0384165f908152600c60205260409020548110612a18576001600160a01b0384165f908152600c6020526040902060068054839081106129f0576129f0614992565b5f918252602080832060016002909302018201548454928301855593835290912001556129a7565b6001600160a01b0383165f908152600c60205260409020548110612a89576001600160a01b0383165f908152600c602052604090206006805483908110612a6157612a61614992565b5f91825260208083206001600290930201820154845492830185559383529091200155612a18565b6001600160a01b0382165f908152600c60205260409020548110612afa576001600160a01b0382165f908152600c602052604090206006805483908110612ad257612ad2614992565b5f91825260208083206001600290930201820154845492830185559383529091200155612a89565b5f612b0485611364565b612b1757612b1285836110e4565b612b19565b5f5b90505f6001600160a01b0386811690861614612b5057612b3885611364565b612b4b57612b4685846110e4565b612b4d565b5f5b90505b6040805160028082526060820183525f9260208301908036833750506040805160028082526060820183529394505f93909250906020830190803683370190505090505f8415612bf25784838281518110612bad57612bad614992565b60200260200101818152505088828281518110612bcc57612bcc614992565b6001600160a01b039092166020928302919091019091015280612bee81614bb1565b9150505b8315612c505783838281518110612c0b57612c0b614992565b60200260200101818152505087828281518110612c2a57612c2a614992565b6001600160a01b039092166020928302919091019091015280612c4c81614bb1565b9150505b5f5b81811015612e3f575f848281518110612c6d57612c6d614992565b60200260200101511115612e375760068781548110612c8e57612c8e614992565b5f91825260209091206002909102015483516001600160a01b039091169063a9059cbb90859084908110612cc457612cc4614992565b6020026020010151868481518110612cde57612cde614992565b60200260200101516040518363ffffffff1660e01b8152600401612d03929190614af0565b6020604051808303815f875af1925050508015612d3d575060408051601f3d908101601f19168201909252612d3a91810190614b09565b60015b15612e3757505f516020614f1b5f395f51905f526001600160a01b031660068881548110612d6d57612d6d614992565b5f9182526020909120600290910201546001600160a01b031603612dbb57838181518110612d9d57612d9d614992565b602002602001015160085f828254612db59190614b9e565b90915550505b60068781548110612dce57612dce614992565b905f5260205f20906002020160010154600c5f858481518110612df357612df3614992565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f208881548110612e2b57612e2b614992565b5f918252602090912001555b600101612c52565b50506001909401935061299c92505050565b6001600160a01b038316612e7b578060025f828254612e709190614949565b90915550612ed89050565b6001600160a01b0383165f9081526020819052604090205481811015612eba5783818360405163391434e360e21b8152600401610b3193929190614b28565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216612ef457600280548290039055612f12565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612f5791815260200190565b60405180910390a3505050565b6040516343d7ef9f60e11b81526060905f516020614ebb5f395f51905f52906387afdf3e90612f979085906004016145f5565b5f60405180830381865afa158015612fb1573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526108099190810190614d65565b5f8082612fe58688614cd3565b612fef9190614b7f565b905080156130085761300881613003610839565b61324e565b5f836130148689614cd3565b61301e9190614b7f565b9050801561304c575f61302f6108a9565b90506001600160a01b0381161561304a5761304a828261324e565b505b6130568183614949565b979650505050505050565b815f0361306c575050565b5f516020614f1b5f395f51905f526001600160a01b03168160a001516001600160a01b03160361310c57608081015160405163a9059cbb60e01b81525f516020614f1b5f395f51905f529163a9059cbb916130cc91908690600401614af0565b6020604051808303815f875af11580156130e8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e9c9190614b09565b60a0810151604051632a8ddb2f60e01b81525f915f516020614ebb5f395f51905f5291632a8ddb2f91613154915f516020614f1b5f395f51905f529190601290600401614bc9565b6040805180830381865afa15801561316e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131929190614c35565b915050600f60099054906101000a90046001600160a01b03166001600160a01b0316635a9ac706828460800151866131cd8760a00151613eed565b6040518563ffffffff1660e01b81526004016131ec9493929190614c62565b5f604051808303815f87803b158015613203575f5ffd5b505af1925050508015613214575060015b610e9c57608082015160405163a9059cbb60e01b81525f516020614f1b5f395f51905f529163a9059cbb9161131e91908790600401614af0565b815f03613259575050565b604051632e1a7d4d60e01b8152600481018390525f516020614f1b5f395f51905f5290632e1a7d4d906024015f604051808303815f87803b15801561329c575f5ffd5b505af19250505080156132ad575060015b6132e35760405163a9059cbb60e01b81525f516020614f1b5f395f51905f529063a9059cbb906130cc9084908690600401614af0565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f811461332c576040519150601f19603f3d011682016040523d82523d5f602084013e613331565b606091505b5050905080610e9c5760405163a9059cbb60e01b81525f516020614f1b5f395f51905f529063a9059cbb9061131e9085908790600401614af0565b815f03613377575050565b5f516020614f1b5f395f51905f526001600160a01b03168160a001516001600160a01b031603613498578160085f8282546133b29190614949565b925050819055505f6133c78260a00151613f20565b90505f6133d330610ccb565b6002546133e09190614b9e565b9050801561135e57806133ff6b204fce5e3e2502611000000086614cd3565b6134099190614b7f565b6006838154811061341c5761341c614992565b905f5260205f2090600202016001015f8282546134399190614949565b925050819055505f516020614f3b5f395f51905f528360a0015130866006868154811061346857613468614992565b905f5260205f209060020201600101544260405161348a959493929190614abf565b60405180910390a150505050565b60a0810151604051632a8ddb2f60e01b81525f915f516020614ebb5f395f51905f5291632a8ddb2f916134e0915f516020614f1b5f395f51905f529190601290600401614bc9565b6040805180830381865afa1580156134fa573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061351e9190614c35565b9150505f8260a001516001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161355291906145f5565b602060405180830381865afa15801561356d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613591919061491e565b9050600f60099054906101000a90046001600160a01b03166001600160a01b0316635a9ac7068330876135c78860a00151613eed565b6040518563ffffffff1660e01b81526004016135e69493929190614c62565b5f604051808303815f87803b1580156135fd575f5ffd5b505af192505050801561360e575060015b1561135e5760a08301516040516370a0823160e01b81525f916001600160a01b0316906370a08231906136459030906004016145f5565b602060405180830381865afa158015613660573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613684919061491e565b90505f6136918383614b9e565b905080156115f3575f6136a78660a00151613f20565b90505f6136b330610ccb565b6002546136c09190614b9e565b9050801561377357806136df6b204fce5e3e2502611000000085614cd3565b6136e99190614b7f565b600683815481106136fc576136fc614992565b905f5260205f2090600202016001015f8282546137199190614949565b925050819055505f516020614f3b5f395f51905f528760a0015130856006868154811061374857613748614992565b905f5260205f209060020201600101544260405161376a959493929190614abf565b60405180910390a15b5050505050505050565b815f03613788575050565b60068101545f81900361379a57505050565b60048201546001600160a01b03165f81158015906137ce57506001600160a01b0382165f516020614f1b5f395f51905f5214155b9050848115613add57604051632a8ddb2f60e01b81525f905f516020614ebb5f395f51905f5290632a8ddb2f9061381b905f516020614f1b5f395f51905f52908890601290600401614bc9565b6040805180830381865afa158015613835573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906138599190614c35565b9150506001600160a01b0381166138735750505050505050565b6040516370a0823160e01b81525f906001600160a01b038616906370a08231906138a19030906004016145f5565b602060405180830381865afa1580156138bc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906138e0919061491e565b600f5460405163095ea7b360e01b81529192505f516020614f1b5f395f51905f529163095ea7b39161392891600160481b9091046001600160a01b0316908c90600401614af0565b6020604051808303815f875af1158015613944573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906139689190614b09565b506040805160028082526060820183525f926020830190803683370190505090505f516020614f1b5f395f51905f52815f815181106139a9576139a9614992565b60200260200101906001600160a01b031690816001600160a01b03168152505085816001815181106139dd576139dd614992565b6001600160a01b039283166020918202929092010152600f54604051637e18437960e01b8152600160481b90910490911690637e18437990613a2990869030908e908790600401614c62565b5f604051808303815f87803b158015613a40575f5ffd5b505af1925050508015613a51575060015b613a6057505050505050505050565b6040516370a0823160e01b815282906001600160a01b038816906370a0823190613a8e9030906004016145f5565b602060405180830381865afa158015613aa9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613acd919061491e565b613ad79190614b9e565b93505050505b5f82613af6575f516020614f1b5f395f51905f52613af8565b835b604051632a8ddb2f60e01b81529091505f905f516020614ebb5f395f51905f5290632a8ddb2f90613b329030908690601290600401614bc9565b6040805180830381865afa158015613b4c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b709190614c35565b9150506001600160a01b038116613b8b575050505050505050565b600f54613bab903090600160481b90046001600160a01b03165f196113e3565b8315613c2f57600f5460405163095ea7b360e01b81526001600160a01b038085169263095ea7b392613bed92600160481b909204909116908790600401614af0565b6020604051808303815f875af1158015613c09573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613c2d9190614b09565b505b600f5460405163863f15cd60e01b81526001600160a01b0383811660048301523060248301528481166044830152606482018990526084820186905261dead60a4830152600160481b9092049091169063863f15cd9060c4015f604051808303815f87803b158015613c9f575f5ffd5b505af1925050508015613cb0575060015b15613773575f6018885f015481548110613ccc57613ccc614992565b905f5260205f209060070201600601819055505050505050505050565b5f8080808085604001516002811115613d0457613d04614647565b03613d2a57613d1c8660400151868860c00151614018565b909450925060019050613db0565b600185604001516002811115613d4257613d42614647565b148015613d50575085606001515b15613d6857613d1c8660400151868860c00151614018565b600285604001516002811115613d8057613d80614647565b148015613d8e575085608001515b15613db057613da68660400151868860c00151614018565b9094509250600190505b80613dc4575f5f5f93509350935050613e1c565b5f8660a00151118015613dd657505f84115b15613e07576127108660a0015185613dee9190614cd3565b613df89190614b7f565b9150613e048285614b9e565b93505b613e1a865f0151876020015186886140b5565b505b9250925092565b5f5f5f846001600160a01b0316866001600160a01b031603613e6657613e4886611364565b613e5a57613e5586610bd9565b613e5c565b5f5b92505f9150613ea5565b613e6f86611364565b613e8157613e7c86610bd9565b613e83565b5f5b9250613e8e85611364565b613ea057613e9b85610bd9565b613ea2565b5f5b91505b613eae84611753565b6007546001600160a01b039586165f90815260096020526040808220839055988716815288812082905596909516865295909420929092559390929150565b6040516377a9efe360e11b81526060905f516020614ebb5f395f51905f529063ef53dfc690612f979085906004016145f5565b5f805b600654811015613f7657826001600160a01b031660068281548110613f4a57613f4a614992565b5f9182526020909120600290910201546001600160a01b031603613f6e5792915050565b600101613f23565b50604080518082019091526001600160a01b0383811682525f6020830181815260068054600180820183559382905294517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f600290960295860180546001600160a01b0319169190951617909355517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d4090930192909255546108099190614b9e565b6060820151604051632b8d28ef60e21b8152600481018590526024810191909152604481018290526001606482015261271060848201525f9081905f516020614ebb5f395f51905f529063ae34a3bc9060a4016040805180830381865afa158015614085573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906140a99190614b5d565b91509150935093915050565b805f01517f4561d7b5bc749427362f16999e4266d5e838624dc76c7915a80597b4303f910682602001518360400151878787426040516140fa96959493929190614e2f565b60405180910390a25f8160200151600581111561411957614119614647565b0361412d5761412884836141f4565b61135e565b60038160200151600581111561414557614145614647565b0361415457614128848361423b565b60028160200151600581111561416c5761416c614647565b0361417c576141288483836142fb565b60018160200151600581111561419457614194614647565b036141a4576141288483836143a8565b6004816020015160058111156141bc576141bc614647565b036141cc57614128848383614458565b6005816020015160058111156141e4576141e4614647565b0361135e5761135e8483836144e7565b8060195f8282546142059190614949565b90915550506040515f516020614e9b5f395f51905f5290614229908390429061495c565b60405180910390a161171b828261171f565b6142468230836124a7565b5f61425030610ccb565b60025461425d9190614b9e565b905080156142b4578061427c6b204fce5e3e2502611000000084614cd3565b6142869190614b7f565b60075f8282546142969190614949565b9250508190555081601b5f8282546142ae9190614949565b90915550505b6007546040805184815260208101929092524282820152517f4aa5b1e7e0aa0cb24a794cb0410918d48c70726a1891006de7d83adf6ec039209181900360600190a1505050565b60808101516001600160a01b03165f9081526013602052604090205460ff166143455760808101516001600160a01b03165f908152601360205260409020805460ff191660011790555b8060e00151156143995761435a8330846124a7565b816018825f01518154811061437157614371614992565b905f5260205f2090600702016006015f82825461438e9190614949565b90915550610e9c9050565b610e9c838260800151846124a7565b600d805460ff191660011790556143c08330846124a7565b816018825f0151815481106143d7576143d7614992565b905f5260205f2090600702016006015f8282546143f49190614949565b9250508190555081601a5f82825461440c9190614949565b90915550508051608082015160a08301516040515f516020614e7b5f395f51905f529361444193879391925f92904290614cea565b60405180910390a15050600d805460ff1916905550565b600d805460ff191660011790556144708330846124a7565b816018825f01518154811061448757614487614992565b905f5260205f2090600702016006015f8282546144a49190614949565b9250508190555081601c5f8282546144bc9190614949565b909155505060a08101516040515f516020614edb5f395f51905f52916144419185915f914290614d1e565b600d805460ff191660011790556144ff8330846124a7565b816018825f01518154811061451657614516614992565b905f5260205f2090600702016006015f8282546145339190614949565b9250508190555081601d5f82825461454b9190614949565b9091555050600d805460ff19169055505050565b602081525f82518060208401525f5b8181101561458b576020818601810151604086840101520161456e565b505f604082850101526040601f19601f83011684010191505092915050565b6001600160a01b0381168114610b05575f5ffd5b5f5f604083850312156145cf575f5ffd5b82356145da816145aa565b946020939093013593505050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b5f5f5f6060848603121561461b575f5ffd5b8335614626816145aa565b92506020840135614636816145aa565b929592945050506040919091013590565b634e487b7160e01b5f52602160045260245ffd5b6006811061466b5761466b614647565b9052565b6003811061466b5761466b614647565b602080825282518282018190525f918401906040840190835b818110156147425783518051845260208101516146b8602086018261465b565b5060408101516146cb604086018261466f565b506060810151606085015260018060a01b03608082015116608085015260018060a01b0360a08201511660a085015260c081015161470c60c08601826145e8565b5060e081015161472060e086018215159052565b5061010090810151908401526020939093019261012090920191600101614698565b509095945050505050565b5f6020828403121561475d575f5ffd5b5035919050565b5f5f60408385031215614775575f5ffd5b823591506020830135614787816145aa565b809150509250929050565b5f602082840312156147a2575f5ffd5b81356111f3816145aa565b602080825282518282018190525f918401906040840190835b818110156147425783518352602093840193909201916001016147c6565b602080825282518282018190525f918401906040840190835b8181101561474257835180516001600160a01b0316845260209081015181850152909301926040909201916001016147fd565b8981526101208101614845602083018b61465b565b614852604083018a61466f565b60608201979097526001600160a01b03958616608082015293851660a08501529190931660c083015291151560e082015261010001529392505050565b5f5f604083850312156148a0575f5ffd5b82356148ab816145aa565b91506020830135614787816145aa565b600181811c908216806148cf57607f821691505b6020821081036148ed57634e487b7160e01b5f52602260045260245ffd5b50919050565b80516148fe816145aa565b919050565b5f60208284031215614913575f5ffd5b81516111f3816145aa565b5f6020828403121561492e575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561080957610809614935565b918252602082015260400190565b6020808252600e908201526d125b9d985b1a59081d185e08125160921b604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b60208082526012908201527127b7363c903330b1ba37b93c9037bbb732b960711b604082015260600190565b6001600160a01b031690565b602080825282548282018190525f848152918220906040840190835b8181101561474257835483526001840154614a1b6020850160ff831661465b565b614a2e6040850160ff8360081c1661466f565b5060028401546060840152614a4660038501546149d2565b614a5360808501826145e8565b50614a6160048501546149d2565b614a6e60a08501826145e8565b506005840154614a8a60c085016001600160a01b0383166145e8565b614a9e60e0850160ff8360a01c1615159052565b506006840154610100840152600790930192610120909201916001016149fa565b6001600160a01b03958616815293909416602084015260408301919091526060820152608081019190915260a00190565b6001600160a01b03929092168252602082015260400190565b5f60208284031215614b19575f5ffd5b815180151581146111f3575f5ffd5b6001600160a01b039390931683526020830191909152604082015260600190565b634e487b7160e01b5f52604160045260245ffd5b5f5f60408385031215614b6e575f5ffd5b505080516020909101519092909150565b5f82614b9957634e487b7160e01b5f52601260045260245ffd5b500490565b8181038181111561080957610809614935565b5f60018201614bc257614bc2614935565b5060010190565b6001600160a01b038481168252831660208083019190915260606040830181905283549083018190525f848152918220906080840190835b81811015614c285783546001600160a01b0316835260019384019360209093019201614c01565b5090979650505050505050565b5f5f60408385031215614c46575f5ffd5b8251614c51816145aa565b6020840151909250614787816145aa565b6001600160a01b03858116825284166020808301919091526040820184905260806060830181905283519083018190525f9184019060a0840190835b81811015614cc55783516001600160a01b0316835260209384019390920191600101614c9e565b509098975050505050505050565b808202811582820484141761080957610809614935565b958652602086019490945260408501929092526001600160a01b03908116606085015216608083015260a082015260c00190565b93845260208401929092526001600160a01b03166040830152606082015260800190565b6001600160a01b0393841681529183166020830152909116604082015260600190565b5f60208284031215614d75575f5ffd5b81516001600160401b03811115614d8a575f5ffd5b8201601f81018413614d9a575f5ffd5b80516001600160401b03811115614db357614db3614b49565b604051600582901b90603f8201601f191681016001600160401b0381118282101715614de157614de1614b49565b604052918252602081840181019290810187841115614dfe575f5ffd5b6020850194505b83851015614e2457614e16856148f3565b815260209485019401614e05565b509695505050505050565b60c08101614e3d828961465b565b614e4a602083018861466f565b6001600160a01b039586166040830152939094166060850152608084019190915260a0909201919091529291505056fe4273856ca27b03e758cdfc9b3b6ca37d494ecb75fbae628757965b75fb104ab6240ac4b1276638a07697a276a1e769aeeef6a875321508eee58718c790a0eb25000000000000000000000000d3397b405a2272f5c27fc673be20579f22f59d6cf7d7115427aac464a6917f7ba3066179fd0c845521f577e53e8e4d4ec97dd4a8799663458a5ef2936f7fa0c99b3336c69c25890f82974f04e811e5bb359186c7000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27c24cdf2085ca2e96c74f42d25648701f34a19b69bce82381dffcf6d00a8dcad5a164736f6c634300081f000a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000b1ae112d59513618a04fd5e83bd7efba05a3f000000000000000000000000d7b71ca606f9a780d81d6581b887b1c9ad9407720000000000000000000000000000000000000000033b2e3c9fd0803ce80000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000cae394005c9c4c309621c53d53db9ceb701fc8d8000000000000000000000000000b1ae112d59513618a04fd5e83bd7efba05a3f000000000000000000000000d3397b405a2272f5c27fc673be20579f22f59d6c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b1ae112d59513618a04fd5e83bd7efba05a3f000000000000000000000000000000000000000002091fb06eec50ca360000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065969656c645800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004594c445800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000000000000000000000000000008577f0fb9d709d5bebd808dddd0094fbaec667b4000000000000000000000000000000000000000000000000000000000000036900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000000000000000000000000000008577f0fb9d709d5bebd808dddd0094fbaec667b4000000000000000000000000000000000000000000000000000000000000036900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c450b3c2b89a2dabe5a3ee39ff475134a30d665000000000000000000000000000000000000000000000000000000000000036900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c450b3c2b89a2dabe5a3ee39ff475134a30d66500000000000000000000000000000000000000000000000000000000000003690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6f8db0aba00007681f8faf16a0fda1c9b030b1100000000000000000000000000000000000000000000000000000000000003690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6f8db0aba00007681f8faf16a0fda1c9b030b1100000000000000000000000000000000000000000000000000000000000003690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f2da3942616880e52e841e5c504b5a9fba23fff000000000000000000000000000000000000000000000000000000000000003690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f2da3942616880e52e841e5c504b5a9fba23fff00000000000000000000000000000000000000000000000000000000000000369000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000dead000000000000000000000000f2da3942616880e52e841e5c504b5a9fba23fff00000000000000000000000000000000000000000000000000000000000000369000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000dead000000000000000000000000f2da3942616880e52e841e5c504b5a9fba23fff0000000000000000000000000000000000000000000000000000000000000036900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000dead0000000000000000000000008577f0fb9d709d5bebd808dddd0094fbaec667b4000000000000000000000000000000000000000000000000000000000000036900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000dead0000000000000000000000008577f0fb9d709d5bebd808dddd0094fbaec667b4000000000000000000000000000000000000000000000000000000000000036900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Deployed ByteCode

0x60806040526004361061021a575f3560e01c8063014182051461022557806306fdde031461024d578063095ea7b31461026e5780630d3ebcbf1461029d57806313299604146102b3578063138dd4d1146102d457806318160ddd146102e857806322849720146102fc57806323b872dd146103115780632973ef2d14610330578063313ce56714610351578063346847b41461036c578063378dc3dc14610380578063406cf2291461039557806342966c68146103a95780634ada218b146103c85780634f30800d146103e157806358232c94146103f5578063695d69b3146104145780636a2072d414610433578063709df63c1461045f57806370a0823114610480578063715018a61461049f5780637922fc01146104b35780637c8b6f09146104c857806384527bbd146105045780638453ef99146105195780638a8c523c1461052d5780638da5cb5b146105415780639045be581461055557806390b8e5981461058357806395d89b41146105a25780639b165f4e146105b6578063a9059cbb146105d5578063ad826ab6146105f4578063b2ff197314610613578063c5be2bc714610627578063cb78c1631461065b578063ce7b63ed1461066f578063ced72f8714610683578063d89135cd14610697578063dd62ed3e146106ac578063e4f8d62e146106cb578063e5711e8b146106ea578063e6375d3e14610709578063eb50c06114610728578063f2fde38b14610747575f5ffd5b3661022157005b5f5ffd5b348015610230575f5ffd5b5061023a601c5481565b6040519081526020015b60405180910390f35b348015610258575f5ffd5b50610261610766565b604051610244919061455f565b348015610279575f5ffd5b5061028d6102883660046145be565b6107f6565b6040519015158152602001610244565b3480156102a8575f5ffd5b506102b161080f565b005b3480156102be575f5ffd5b506102c7610839565b60405161024491906145f5565b3480156102df575f5ffd5b506102c76108a9565b3480156102f3575f5ffd5b5060025461023a565b348015610307575f5ffd5b5061023a601b5481565b34801561031c575f5ffd5b5061028d61032b366004614609565b6108f0565b34801561033b575f5ffd5b50610344610913565b604051610244919061467f565b34801561035c575f5ffd5b5060405160128152602001610244565b348015610377575f5ffd5b5061023a610a42565b34801561038b575f5ffd5b5061023a600e5481565b3480156103a0575f5ffd5b5061028d610aad565b3480156103b4575f5ffd5b506102b16103c336600461474d565b610abe565b3480156103d3575f5ffd5b50600f5461028d9060ff1681565b3480156103ec575f5ffd5b5060075461023a565b348015610400575f5ffd5b506102b161040f366004614764565b610b08565b34801561041f575f5ffd5b5061023a61042e366004614792565b610bd9565b34801561043e575f5ffd5b5061045261044d366004614792565b610bf8565b60405161024491906147ad565b34801561046a575f5ffd5b50610473610c61565b60405161024491906147e4565b34801561048b575f5ffd5b5061023a61049a366004614792565b610ccb565b3480156104aa575f5ffd5b506102b1610ce5565b3480156104be575f5ffd5b5061023a601d5481565b3480156104d3575f5ffd5b50600f546104ec9061010090046001600160401b031681565b6040516001600160401b039091168152602001610244565b34801561050f575f5ffd5b5061023a601a5481565b348015610524575f5ffd5b506102b1610cf6565b348015610538575f5ffd5b506102b1610d08565b34801561054c575f5ffd5b506102c7610d58565b348015610560575f5ffd5b5061028d61056f366004614792565b600a6020525f908152604090205460ff1681565b34801561058e575f5ffd5b506102b161059d3660046145be565b610d67565b3480156105ad575f5ffd5b50610261610ea1565b3480156105c1575f5ffd5b506102b16105d0366004614792565b610eb0565b3480156105e0575f5ffd5b5061028d6105ef3660046145be565b610edb565b3480156105ff575f5ffd5b506102b161060e366004614764565b610ee8565b34801561061e575f5ffd5b5060165461023a565b348015610632575f5ffd5b5061064661064136600461474d565b610fb1565b60405161024499989796959493929190614830565b348015610666575f5ffd5b5061023a611026565b34801561067a575f5ffd5b5060155461023a565b34801561068e575f5ffd5b5061023a611073565b3480156106a2575f5ffd5b5061023a60195481565b3480156106b7575f5ffd5b5061023a6106c636600461488f565b6110ba565b3480156106d6575f5ffd5b5061023a6106e53660046145be565b6110e4565b3480156106f5575f5ffd5b506102b1610704366004614609565b6111fa565b348015610714575f5ffd5b5061028d610723366004614792565b611364565b348015610733575f5ffd5b506102b1610742366004614792565b611381565b348015610752575f5ffd5b506102b1610761366004614792565b6113a9565b606060038054610775906148bb565b80601f01602080910402602001604051908101604052809291908181526020018280546107a1906148bb565b80156107ec5780601f106107c3576101008083540402835291602001916107ec565b820191905f5260205f20905b8154815290600101906020018083116107cf57829003601f168201915b5050505050905090565b5f336108038185856113e3565b60019150505b92915050565b6108176113f0565b600f54610837903090600160481b90046001600160a01b03165f196113e3565b565b601154604080516336ce6de360e11b815290515f926001600160a01b031691636d9cdbc69160048083019260209291908290030181865afa158015610880573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108a49190614903565b905090565b60115460408051637bb8996d60e01b815290515f926001600160a01b031691637bb8996d9160048083019260209291908290030181865afa158015610880573d5f5f3e3d5ffd5b5f336108fd858285611422565b61090885858561146d565b506001949350505050565b60606018805480602002602001604051908101604052809291908181526020015f905b82821015610a39578382905f5260205f209060070201604051806101200160405290815f8201548152602001600182015f9054906101000a900460ff16600581111561098457610984614647565b600581111561099557610995614647565b81526020016001820160019054906101000a900460ff1660028111156109bd576109bd614647565b60028111156109ce576109ce614647565b8152600282015460208083019190915260038301546001600160a01b03908116604084015260048401548116606084015260058401549081166080840152600160a01b900460ff16151560a083015260069092015460c0909101529082526001929092019101610936565b50505050905090565b6011546040805163b5a08dd160e01b815290515f926001600160a01b03169163b5a08dd19160048083019260209291908290030181865afa158015610a89573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108a4919061491e565b5f610ab833336116f1565b50600190565b8060195f828254610acf9190614949565b90915550506040515f516020614e9b5f395f51905f5290610af3908390429061495c565b60405180910390a1610b05338261171f565b50565b610b106113f0565b6018548210610b3a5760405162461bcd60e51b8152600401610b319061496a565b60405180910390fd5b6001600160a01b038116610b8f5760405162461bcd60e51b815260206004820152601c60248201527b546f6b656e20616464726573732063616e6e6f74206265207a65726f60201b6044820152606401610b31565b8060188381548110610ba357610ba3614992565b905f5260205f2090600702016004015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b5f610be382611364565b15610bef57505f919050565b61080982611753565b6001600160a01b0381165f908152600c6020908152604091829020805483518184028101840190945280845260609392830182828015610c5557602002820191905f5260205f20905b815481526020019060010190808311610c41575b50505050509050919050565b60606006805480602002602001604051908101604052809291908181526020015f905b82821015610a39575f848152602090819020604080518082019091526002850290910180546001600160a01b03168252600190810154828401529083529092019101610c84565b6001600160a01b03165f9081526020819052604090205490565b610ced6113f0565b6108375f6117f0565b610cfe6113f0565b6108375f19611841565b610d106113f0565b600f5460ff1615610d3457604051637952fbad60e11b815260040160405180910390fd5b600f805460ff191660011790556040515f516020614efb5f395f51905f52905f90a1565b6005546001600160a01b031690565b60115f9054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610db7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ddb9190614903565b6001600160a01b0316336001600160a01b031614610e0b5760405162461bcd60e51b8152600401610b31906149a6565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114610e54576040519150601f19603f3d011682016040523d82523d5f602084013e610e59565b606091505b5050905080610e9c5760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b6044820152606401610b31565b505050565b606060048054610775906148bb565b610eb86113f0565b6001600160a01b03165f908152601360205260409020805460ff19166001179055565b5f3361080381858561146d565b610ef06113f0565b6018548210610f115760405162461bcd60e51b8152600401610b319061496a565b6001600160a01b038116610f675760405162461bcd60e51b815260206004820152601f60248201527f52656365697665722063616e6e6f74206265207a65726f2061646472657373006044820152606401610b31565b8060188381548110610f7b57610f7b614992565b905f5260205f2090600702016003015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b60188181548110610fc0575f80fd5b5f918252602090912060079091020180546001820154600283015460038401546004850154600586015460069096015494965060ff8085169661010090950481169593946001600160a01b039384169492841693811692600160a01b9091049091169089565b604051625f8d8f60e81b81525f905f516020614ebb5f395f51905f5290635f8d8f0090611058906018906004016149de565b602060405180830381865afa158015610a89573d5f5f3e3d5ffd5b6011546040805163c57981b560e01b815290515f926001600160a01b03169163c57981b59160048083019260209291908290030181865afa158015610a89573d5f5f3e3d5ffd5b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6001600160a01b0382165f908152600c6020526040812054821061110957505f610809565b5f516020614ebb5f395f51905f526001600160a01b031663a89055e584306006868154811061113a5761113a614992565b905f5260205f20906002020160010154600c5f896001600160a01b03166001600160a01b031681526020019081526020015f20878154811061117e5761117e614992565b905f5260205f2001546b204fce5e3e250261100000006040518663ffffffff1660e01b81526004016111b4959493929190614abf565b602060405180830381865afa1580156111cf573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111f3919061491e565b9392505050565b60115f9054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561124a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061126e9190614903565b6001600160a01b0316336001600160a01b03161461129e5760405162461bcd60e51b8152600401610b31906149a6565b306001600160a01b038416036112f05760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103932b9b1bab29037bbb7103a37b5b2b760491b6044820152606401610b31565b60405163a9059cbb60e01b81526001600160a01b0384169063a9059cbb9061131e9085908590600401614af0565b6020604051808303815f875af115801561133a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061135e9190614b09565b50505050565b6001600160a01b03165f908152600a602052604090205460ff1690565b6113896113f0565b6001600160a01b03165f908152601360205260409020805460ff19169055565b6113b16113f0565b6001600160a01b0381166113da575f604051631e4fbdf760e01b8152600401610b3191906145f5565b610b05816117f0565b610e9c8383836001612322565b336113f9610d58565b6001600160a01b031614610837573360405163118cdaa760e01b8152600401610b3191906145f5565b5f61142d84846110ba565b90505f1981101561135e578181101561145f57828183604051637dc7a0d960e11b8152600401610b3193929190614b28565b61135e84848484035f612322565b6017805460ff60201b19169055600f546001600160a01b0384165f9081526013602052604090205460ff9182169116811580156114b95750600f5461010090046001600160401b031615155b80156114d55750600f5461010090046001600160401b03164210155b1561150357600f805460ff191660019081179091556040519092505f516020614efb5f395f51905f52905f90a15b61150c846123f4565b156115225761151b858461171f565b5050505050565b8115801561152e575080155b1561154c5760405163bcb8b8fb60e01b815260040160405180910390fd5b5f6115568561242c565b601854909150158061157257506017546301000000900460ff16155b8061157a5750815b8061159c57506001600160a01b0385165f9081526013602052604090205460ff165b806115a95750600d5460ff165b156115fb576017546301000000900460ff161580156115c55750805b156115de576017805463ff000000191663010000001790555b6115e886866116f1565b6115f38686866124a7565b505050505050565b80801561162057506001600160a01b0385165f908152600a602052604090205460ff16155b15611648576001600160a01b0385165f908152600a60205260409020805460ff191660011790555b5f6116538787612504565b90505f8161166a576116658888612579565b61166c565b5f5b90505f61167c89898986866125d4565b60175490915060ff16801561169b5750601754600160201b900460ff16155b80156116a5575082155b156116c7576116b387611841565b6017805460ff60201b1916600160201b1790555b6116d189896116f1565b6116db898961289c565b6116e68989836124a7565b505050505050505050565b60175462010000900460ff161561171b5760105461171b90839083906001600160a01b031661299a565b5050565b6001600160a01b038216611748575f604051634b637e8f60e11b8152600401610b3191906145f5565b61171b825f83612e51565b6007546001600160a01b0382165f90815260096020526040808220549051631d2fa43b60e11b815291925f516020614ebb5f395f51905f5292633a5f4876926117b19287923092906b204fce5e3e2502611000000090600401614abf565b602060405180830381865afa1580156117cc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610809919061491e565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b600d805460ff191660011790556018545f90819081816001600160401b0381111561186e5761186e614b49565b604051908082528060200260200182016040528015611897578160200160208202803683370190505b5090505f826001600160401b038111156118b3576118b3614b49565b6040519080825280602002602001820160405280156118dc578160200160208202803683370190505b5090505f5b83811015611b44575f601882815481106118fd576118fd614992565b905f5260205f209060070201905080600601545f0361191c5750611b3c565b60018082015460ff16600581111561193657611936614647565b148061197057506002600182015460ff16600581111561195857611958614647565b14801561197057506005810154600160a01b900460ff165b8061199357506004600182015460ff16600581111561199157611991614647565b145b806119b657506005600182015460ff1660058111156119b4576119b4614647565b145b15611b3a57600681015460405163059b6d4760e21b81525f9182915f516020614ebb5f395f51905f529163166db51c916119f591908e9060040161495c565b6040805180830381865afa158015611a0f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a339190614b5d565b90925090508115611b0f5781816005600186015460ff166005811115611a5b57611a5b614647565b03611a8457611a6b600285614b7f565b9150611a778285614b9e565b611a819084614949565b90505b6001888781518110611a9857611a98614992565b60200260200101901515908115158152505081878781518110611abd57611abd614992565b6020908102919091010152611ad2828c614949565b9a5089611ade81614bb1565b9a50508060188781548110611af557611af5614992565b905f5260205f209060070201600601819055505050611b37565b8060188581548110611b2357611b23614992565b905f5260205f209060070201600601819055505b50505b505b6001016118e1565b50604051632a8ddb2f60e01b81525f905f516020614ebb5f395f51905f5290632a8ddb2f90611b899030905f516020614f1b5f395f51905f5290601290600401614bc9565b6040805180830381865afa158015611ba3573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bc79190614c35565b9150506001600160a01b038116611c0b576040517f34be9cb68ddf4eeebba29ea0e1db420286ea39e4ce7a377e66a7b47a998a6d03905f90a1505050505050612315565b5f5f5f5f5f516020614ebb5f395f51905f526001600160a01b031663166db51c6015548d6040518363ffffffff1660e01b8152600401611c4c92919061495c565b6040805180830381865afa158015611c66573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c8a9190614b5d565b60165460405163059b6d4760e21b81529296509093505f516020614ebb5f395f51905f529163166db51c91611cc3918f9060040161495c565b6040805180830381865afa158015611cdd573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d019190614b5d565b601593909355601692909255509050611d1a8289614949565b9750611d268189614949565b9750875f03611d3c575050505050505050612315565b600f54600160481b90046001600160a01b0316637e18437984308b611d6082612f64565b6040518563ffffffff1660e01b8152600401611d7f9493929190614c62565b5f604051808303815f87803b158015611d96575f5ffd5b505af1925050508015611da7575060015b611e69575f5b86811015611e2c57858181518110611dc757611dc7614992565b602002602001015115611e2457848181518110611de657611de6614992565b602002602001015160188281548110611e0157611e01614992565b905f5260205f2090600702016006015f828254611e1e9190614949565b90915550505b600101611dad565b508160155f828254611e3e9190614949565b925050819055508060165f828254611e569190614949565b9091555061231598505050505050505050565b6008546040516370a0823160e01b81525f91905f516020614f1b5f395f51905f52906370a0823190611e9f9030906004016145f5565b602060405180830381865afa158015611eba573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ede919061491e565b611ee89190614b9e565b9050611ef68184848c612fd8565b611f009082614b9e565b9050611f0c838a614b9e565b9850611f18828a614b9e565b9850805f03611f2f57505050505050505050612315565b5f5b8781101561230a57868181518110611f4b57611f4b614992565b60200260200101511580611f775750858181518110611f6c57611f6c614992565b60200260200101515f145b612302575f8a83888481518110611f9057611f90614992565b6020026020010151611fa29190614cd3565b611fac9190614b7f565b90505f60188381548110611fc257611fc2614992565b5f9182526020909120600790910201905060018082015460ff166005811115611fed57611fed614647565b03612133575f516020614e7b5f395f51905f5288848151811061201257612012614992565b602090810291909101015182546003840154600485015460405161204a94939288926001600160a01b03918216929116904290614cea565b60405180910390a160408051610120810190915281548152600182015461212e9184918490602083019060ff16600581111561208857612088614647565b600581111561209957612099614647565b81526020016001820160019054906101000a900460ff1660028111156120c1576120c1614647565b60028111156120d2576120d2614647565b81526002820154602082015260038201546001600160a01b03908116604083015260048301548116606083015260058301549081166080830152600160a01b900460ff16151560a082015260069091015460c090910152613061565b6122ff565b6002600182015460ff16600581111561214e5761214e614647565b14801561216657506005810154600160a01b900460ff165b1561218457600381015461212e9083906001600160a01b031661324e565b6004600182015460ff16600581111561219f5761219f614647565b036122d5575f516020614edb5f395f51905f528884815181106121c4576121c4614992565b602090810291909101015160048301546040516121f1929186916001600160a01b03909116904290614d1e565b60405180910390a160408051610120810190915281548152600182015461212e9184918490602083019060ff16600581111561222f5761222f614647565b600581111561224057612240614647565b81526020016001820160019054906101000a900460ff16600281111561226857612268614647565b600281111561227957612279614647565b81526002820154602082015260038201546001600160a01b03908116604083015260048301548116606083015260058301549081166080830152600160a01b900460ff16151560a082015260069091015460c09091015261336c565b6005600182015460ff1660058111156122f0576122f0614647565b036122ff576122ff828261377d565b50505b600101611f31565b505050505050505050505b50600d805460ff19169055565b6001600160a01b03841661234b575f60405163e602df0560e01b8152600401610b3191906145f5565b6001600160a01b038316612374575f604051634a1406b160e11b8152600401610b3191906145f5565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561135e57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516123e691815260200190565b60405180910390a350505050565b5f6001600160a01b038216158061241557506103696001600160a01b038316145b806108095750506001600160a01b031661dead1490565b604051630d5c7b5d60e41b81526001600160a01b03821660048201523060248201525f905f516020614ebb5f395f51905f529063d5c7b5d090604401602060405180830381865afa158015612483573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108099190614b09565b6001600160a01b0383166124d0575f604051634b637e8f60e11b8152600401610b3191906145f5565b6001600160a01b0382166124f9575f60405163ec442f0560e01b8152600401610b3191906145f5565b610e9c838383612e51565b604051636468b51760e01b81525f905f516020614ebb5f395f51905f5290636468b5179061253a90869086903090600401614d42565b602060405180830381865afa158015612555573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111f39190614b09565b5f6125838361242c565b801561259357506125938261242c565b156125a057506001610809565b60405163154b004960e31b81525f516020614ebb5f395f51905f529063aa5802489061253a90869086903090600401614d42565b6040805160e0810182525f60a0820181905260c082018190526001600160a01b03888116835287166020830152918101859052831515606082015282151560808201526017548291829182919060ff16801561264057505f6126346108a9565b6001600160a01b031614155b156126535761264d610a42565b60a08201525b61265b611073565b60c082015260188054604080516020808402820181019092528281525f9390929091849084015b82821015612785578382905f5260205f209060070201604051806101200160405290815f8201548152602001600182015f9054906101000a900460ff1660058111156126d0576126d0614647565b60058111156126e1576126e1614647565b81526020016001820160019054906101000a900460ff16600281111561270957612709614647565b600281111561271a5761271a614647565b8152600282015460208083019190915260038301546001600160a01b03908116604084015260048401548116606084015260058401549081166080840152600160a01b900460ff16151560a083015260069092015460c0909101529082526001929092019101612682565b505082519293505f9150505b818110156127f9575f5f5f6127bf878786815181106127b2576127b2614992565b6020026020010151613ce9565b919450925090506127d0838b614949565b99506127dc828a614949565b98506127e88189614949565b975050600190920191506127919050565b5084156128445760175460ff1615612832576128168c30876124a7565b8460155f8282546128279190614949565b909155506128449050565b6128448c61283e610839565b876124a7565b831561286c576128558c30866124a7565b8360165f8282546128669190614949565b90915550505b8385612878888d614b9e565b6128829190614b9e565b61288c9190614b9e565b9c9b505050505050505050505050565b601754610100900460ff166128af575050565b6010545f90819081906128ce90869086906001600160a01b0316613e23565b600754604080516001600160a01b03808c1682528a166020820152908101859052606081018490526080810183905260a08101919091524260c082015292955090935091507f7f2255e92a9403cf8dd4b9f679ad1f5f5ce9226dd19b0faf14c84bace34d235b9060e00160405180910390a1821561295e5761294f8561242c565b61295e5761295e3086856124a7565b811561297c5761296d8461242c565b61297c5761297c3085846124a7565b801561151b5760105461151b9030906001600160a01b0316836124a7565b5f5b60065481101561135e575b6001600160a01b0384165f908152600c60205260409020548110612a18576001600160a01b0384165f908152600c6020526040902060068054839081106129f0576129f0614992565b5f918252602080832060016002909302018201548454928301855593835290912001556129a7565b6001600160a01b0383165f908152600c60205260409020548110612a89576001600160a01b0383165f908152600c602052604090206006805483908110612a6157612a61614992565b5f91825260208083206001600290930201820154845492830185559383529091200155612a18565b6001600160a01b0382165f908152600c60205260409020548110612afa576001600160a01b0382165f908152600c602052604090206006805483908110612ad257612ad2614992565b5f91825260208083206001600290930201820154845492830185559383529091200155612a89565b5f612b0485611364565b612b1757612b1285836110e4565b612b19565b5f5b90505f6001600160a01b0386811690861614612b5057612b3885611364565b612b4b57612b4685846110e4565b612b4d565b5f5b90505b6040805160028082526060820183525f9260208301908036833750506040805160028082526060820183529394505f93909250906020830190803683370190505090505f8415612bf25784838281518110612bad57612bad614992565b60200260200101818152505088828281518110612bcc57612bcc614992565b6001600160a01b039092166020928302919091019091015280612bee81614bb1565b9150505b8315612c505783838281518110612c0b57612c0b614992565b60200260200101818152505087828281518110612c2a57612c2a614992565b6001600160a01b039092166020928302919091019091015280612c4c81614bb1565b9150505b5f5b81811015612e3f575f848281518110612c6d57612c6d614992565b60200260200101511115612e375760068781548110612c8e57612c8e614992565b5f91825260209091206002909102015483516001600160a01b039091169063a9059cbb90859084908110612cc457612cc4614992565b6020026020010151868481518110612cde57612cde614992565b60200260200101516040518363ffffffff1660e01b8152600401612d03929190614af0565b6020604051808303815f875af1925050508015612d3d575060408051601f3d908101601f19168201909252612d3a91810190614b09565b60015b15612e3757505f516020614f1b5f395f51905f526001600160a01b031660068881548110612d6d57612d6d614992565b5f9182526020909120600290910201546001600160a01b031603612dbb57838181518110612d9d57612d9d614992565b602002602001015160085f828254612db59190614b9e565b90915550505b60068781548110612dce57612dce614992565b905f5260205f20906002020160010154600c5f858481518110612df357612df3614992565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f208881548110612e2b57612e2b614992565b5f918252602090912001555b600101612c52565b50506001909401935061299c92505050565b6001600160a01b038316612e7b578060025f828254612e709190614949565b90915550612ed89050565b6001600160a01b0383165f9081526020819052604090205481811015612eba5783818360405163391434e360e21b8152600401610b3193929190614b28565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216612ef457600280548290039055612f12565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612f5791815260200190565b60405180910390a3505050565b6040516343d7ef9f60e11b81526060905f516020614ebb5f395f51905f52906387afdf3e90612f979085906004016145f5565b5f60405180830381865afa158015612fb1573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526108099190810190614d65565b5f8082612fe58688614cd3565b612fef9190614b7f565b905080156130085761300881613003610839565b61324e565b5f836130148689614cd3565b61301e9190614b7f565b9050801561304c575f61302f6108a9565b90506001600160a01b0381161561304a5761304a828261324e565b505b6130568183614949565b979650505050505050565b815f0361306c575050565b5f516020614f1b5f395f51905f526001600160a01b03168160a001516001600160a01b03160361310c57608081015160405163a9059cbb60e01b81525f516020614f1b5f395f51905f529163a9059cbb916130cc91908690600401614af0565b6020604051808303815f875af11580156130e8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e9c9190614b09565b60a0810151604051632a8ddb2f60e01b81525f915f516020614ebb5f395f51905f5291632a8ddb2f91613154915f516020614f1b5f395f51905f529190601290600401614bc9565b6040805180830381865afa15801561316e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131929190614c35565b915050600f60099054906101000a90046001600160a01b03166001600160a01b0316635a9ac706828460800151866131cd8760a00151613eed565b6040518563ffffffff1660e01b81526004016131ec9493929190614c62565b5f604051808303815f87803b158015613203575f5ffd5b505af1925050508015613214575060015b610e9c57608082015160405163a9059cbb60e01b81525f516020614f1b5f395f51905f529163a9059cbb9161131e91908790600401614af0565b815f03613259575050565b604051632e1a7d4d60e01b8152600481018390525f516020614f1b5f395f51905f5290632e1a7d4d906024015f604051808303815f87803b15801561329c575f5ffd5b505af19250505080156132ad575060015b6132e35760405163a9059cbb60e01b81525f516020614f1b5f395f51905f529063a9059cbb906130cc9084908690600401614af0565b5f816001600160a01b0316836040515f6040518083038185875af1925050503d805f811461332c576040519150601f19603f3d011682016040523d82523d5f602084013e613331565b606091505b5050905080610e9c5760405163a9059cbb60e01b81525f516020614f1b5f395f51905f529063a9059cbb9061131e9085908790600401614af0565b815f03613377575050565b5f516020614f1b5f395f51905f526001600160a01b03168160a001516001600160a01b031603613498578160085f8282546133b29190614949565b925050819055505f6133c78260a00151613f20565b90505f6133d330610ccb565b6002546133e09190614b9e565b9050801561135e57806133ff6b204fce5e3e2502611000000086614cd3565b6134099190614b7f565b6006838154811061341c5761341c614992565b905f5260205f2090600202016001015f8282546134399190614949565b925050819055505f516020614f3b5f395f51905f528360a0015130866006868154811061346857613468614992565b905f5260205f209060020201600101544260405161348a959493929190614abf565b60405180910390a150505050565b60a0810151604051632a8ddb2f60e01b81525f915f516020614ebb5f395f51905f5291632a8ddb2f916134e0915f516020614f1b5f395f51905f529190601290600401614bc9565b6040805180830381865afa1580156134fa573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061351e9190614c35565b9150505f8260a001516001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161355291906145f5565b602060405180830381865afa15801561356d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613591919061491e565b9050600f60099054906101000a90046001600160a01b03166001600160a01b0316635a9ac7068330876135c78860a00151613eed565b6040518563ffffffff1660e01b81526004016135e69493929190614c62565b5f604051808303815f87803b1580156135fd575f5ffd5b505af192505050801561360e575060015b1561135e5760a08301516040516370a0823160e01b81525f916001600160a01b0316906370a08231906136459030906004016145f5565b602060405180830381865afa158015613660573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613684919061491e565b90505f6136918383614b9e565b905080156115f3575f6136a78660a00151613f20565b90505f6136b330610ccb565b6002546136c09190614b9e565b9050801561377357806136df6b204fce5e3e2502611000000085614cd3565b6136e99190614b7f565b600683815481106136fc576136fc614992565b905f5260205f2090600202016001015f8282546137199190614949565b925050819055505f516020614f3b5f395f51905f528760a0015130856006868154811061374857613748614992565b905f5260205f209060020201600101544260405161376a959493929190614abf565b60405180910390a15b5050505050505050565b815f03613788575050565b60068101545f81900361379a57505050565b60048201546001600160a01b03165f81158015906137ce57506001600160a01b0382165f516020614f1b5f395f51905f5214155b9050848115613add57604051632a8ddb2f60e01b81525f905f516020614ebb5f395f51905f5290632a8ddb2f9061381b905f516020614f1b5f395f51905f52908890601290600401614bc9565b6040805180830381865afa158015613835573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906138599190614c35565b9150506001600160a01b0381166138735750505050505050565b6040516370a0823160e01b81525f906001600160a01b038616906370a08231906138a19030906004016145f5565b602060405180830381865afa1580156138bc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906138e0919061491e565b600f5460405163095ea7b360e01b81529192505f516020614f1b5f395f51905f529163095ea7b39161392891600160481b9091046001600160a01b0316908c90600401614af0565b6020604051808303815f875af1158015613944573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906139689190614b09565b506040805160028082526060820183525f926020830190803683370190505090505f516020614f1b5f395f51905f52815f815181106139a9576139a9614992565b60200260200101906001600160a01b031690816001600160a01b03168152505085816001815181106139dd576139dd614992565b6001600160a01b039283166020918202929092010152600f54604051637e18437960e01b8152600160481b90910490911690637e18437990613a2990869030908e908790600401614c62565b5f604051808303815f87803b158015613a40575f5ffd5b505af1925050508015613a51575060015b613a6057505050505050505050565b6040516370a0823160e01b815282906001600160a01b038816906370a0823190613a8e9030906004016145f5565b602060405180830381865afa158015613aa9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613acd919061491e565b613ad79190614b9e565b93505050505b5f82613af6575f516020614f1b5f395f51905f52613af8565b835b604051632a8ddb2f60e01b81529091505f905f516020614ebb5f395f51905f5290632a8ddb2f90613b329030908690601290600401614bc9565b6040805180830381865afa158015613b4c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b709190614c35565b9150506001600160a01b038116613b8b575050505050505050565b600f54613bab903090600160481b90046001600160a01b03165f196113e3565b8315613c2f57600f5460405163095ea7b360e01b81526001600160a01b038085169263095ea7b392613bed92600160481b909204909116908790600401614af0565b6020604051808303815f875af1158015613c09573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613c2d9190614b09565b505b600f5460405163863f15cd60e01b81526001600160a01b0383811660048301523060248301528481166044830152606482018990526084820186905261dead60a4830152600160481b9092049091169063863f15cd9060c4015f604051808303815f87803b158015613c9f575f5ffd5b505af1925050508015613cb0575060015b15613773575f6018885f015481548110613ccc57613ccc614992565b905f5260205f209060070201600601819055505050505050505050565b5f8080808085604001516002811115613d0457613d04614647565b03613d2a57613d1c8660400151868860c00151614018565b909450925060019050613db0565b600185604001516002811115613d4257613d42614647565b148015613d50575085606001515b15613d6857613d1c8660400151868860c00151614018565b600285604001516002811115613d8057613d80614647565b148015613d8e575085608001515b15613db057613da68660400151868860c00151614018565b9094509250600190505b80613dc4575f5f5f93509350935050613e1c565b5f8660a00151118015613dd657505f84115b15613e07576127108660a0015185613dee9190614cd3565b613df89190614b7f565b9150613e048285614b9e565b93505b613e1a865f0151876020015186886140b5565b505b9250925092565b5f5f5f846001600160a01b0316866001600160a01b031603613e6657613e4886611364565b613e5a57613e5586610bd9565b613e5c565b5f5b92505f9150613ea5565b613e6f86611364565b613e8157613e7c86610bd9565b613e83565b5f5b9250613e8e85611364565b613ea057613e9b85610bd9565b613ea2565b5f5b91505b613eae84611753565b6007546001600160a01b039586165f90815260096020526040808220839055988716815288812082905596909516865295909420929092559390929150565b6040516377a9efe360e11b81526060905f516020614ebb5f395f51905f529063ef53dfc690612f979085906004016145f5565b5f805b600654811015613f7657826001600160a01b031660068281548110613f4a57613f4a614992565b5f9182526020909120600290910201546001600160a01b031603613f6e5792915050565b600101613f23565b50604080518082019091526001600160a01b0383811682525f6020830181815260068054600180820183559382905294517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f600290960295860180546001600160a01b0319169190951617909355517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d4090930192909255546108099190614b9e565b6060820151604051632b8d28ef60e21b8152600481018590526024810191909152604481018290526001606482015261271060848201525f9081905f516020614ebb5f395f51905f529063ae34a3bc9060a4016040805180830381865afa158015614085573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906140a99190614b5d565b91509150935093915050565b805f01517f4561d7b5bc749427362f16999e4266d5e838624dc76c7915a80597b4303f910682602001518360400151878787426040516140fa96959493929190614e2f565b60405180910390a25f8160200151600581111561411957614119614647565b0361412d5761412884836141f4565b61135e565b60038160200151600581111561414557614145614647565b0361415457614128848361423b565b60028160200151600581111561416c5761416c614647565b0361417c576141288483836142fb565b60018160200151600581111561419457614194614647565b036141a4576141288483836143a8565b6004816020015160058111156141bc576141bc614647565b036141cc57614128848383614458565b6005816020015160058111156141e4576141e4614647565b0361135e5761135e8483836144e7565b8060195f8282546142059190614949565b90915550506040515f516020614e9b5f395f51905f5290614229908390429061495c565b60405180910390a161171b828261171f565b6142468230836124a7565b5f61425030610ccb565b60025461425d9190614b9e565b905080156142b4578061427c6b204fce5e3e2502611000000084614cd3565b6142869190614b7f565b60075f8282546142969190614949565b9250508190555081601b5f8282546142ae9190614949565b90915550505b6007546040805184815260208101929092524282820152517f4aa5b1e7e0aa0cb24a794cb0410918d48c70726a1891006de7d83adf6ec039209181900360600190a1505050565b60808101516001600160a01b03165f9081526013602052604090205460ff166143455760808101516001600160a01b03165f908152601360205260409020805460ff191660011790555b8060e00151156143995761435a8330846124a7565b816018825f01518154811061437157614371614992565b905f5260205f2090600702016006015f82825461438e9190614949565b90915550610e9c9050565b610e9c838260800151846124a7565b600d805460ff191660011790556143c08330846124a7565b816018825f0151815481106143d7576143d7614992565b905f5260205f2090600702016006015f8282546143f49190614949565b9250508190555081601a5f82825461440c9190614949565b90915550508051608082015160a08301516040515f516020614e7b5f395f51905f529361444193879391925f92904290614cea565b60405180910390a15050600d805460ff1916905550565b600d805460ff191660011790556144708330846124a7565b816018825f01518154811061448757614487614992565b905f5260205f2090600702016006015f8282546144a49190614949565b9250508190555081601c5f8282546144bc9190614949565b909155505060a08101516040515f516020614edb5f395f51905f52916144419185915f914290614d1e565b600d805460ff191660011790556144ff8330846124a7565b816018825f01518154811061451657614516614992565b905f5260205f2090600702016006015f8282546145339190614949565b9250508190555081601d5f82825461454b9190614949565b9091555050600d805460ff19169055505050565b602081525f82518060208401525f5b8181101561458b576020818601810151604086840101520161456e565b505f604082850101526040601f19601f83011684010191505092915050565b6001600160a01b0381168114610b05575f5ffd5b5f5f604083850312156145cf575f5ffd5b82356145da816145aa565b946020939093013593505050565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b5f5f5f6060848603121561461b575f5ffd5b8335614626816145aa565b92506020840135614636816145aa565b929592945050506040919091013590565b634e487b7160e01b5f52602160045260245ffd5b6006811061466b5761466b614647565b9052565b6003811061466b5761466b614647565b602080825282518282018190525f918401906040840190835b818110156147425783518051845260208101516146b8602086018261465b565b5060408101516146cb604086018261466f565b506060810151606085015260018060a01b03608082015116608085015260018060a01b0360a08201511660a085015260c081015161470c60c08601826145e8565b5060e081015161472060e086018215159052565b5061010090810151908401526020939093019261012090920191600101614698565b509095945050505050565b5f6020828403121561475d575f5ffd5b5035919050565b5f5f60408385031215614775575f5ffd5b823591506020830135614787816145aa565b809150509250929050565b5f602082840312156147a2575f5ffd5b81356111f3816145aa565b602080825282518282018190525f918401906040840190835b818110156147425783518352602093840193909201916001016147c6565b602080825282518282018190525f918401906040840190835b8181101561474257835180516001600160a01b0316845260209081015181850152909301926040909201916001016147fd565b8981526101208101614845602083018b61465b565b614852604083018a61466f565b60608201979097526001600160a01b03958616608082015293851660a08501529190931660c083015291151560e082015261010001529392505050565b5f5f604083850312156148a0575f5ffd5b82356148ab816145aa565b91506020830135614787816145aa565b600181811c908216806148cf57607f821691505b6020821081036148ed57634e487b7160e01b5f52602260045260245ffd5b50919050565b80516148fe816145aa565b919050565b5f60208284031215614913575f5ffd5b81516111f3816145aa565b5f6020828403121561492e575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561080957610809614935565b918252602082015260400190565b6020808252600e908201526d125b9d985b1a59081d185e08125160921b604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b60208082526012908201527127b7363c903330b1ba37b93c9037bbb732b960711b604082015260600190565b6001600160a01b031690565b602080825282548282018190525f848152918220906040840190835b8181101561474257835483526001840154614a1b6020850160ff831661465b565b614a2e6040850160ff8360081c1661466f565b5060028401546060840152614a4660038501546149d2565b614a5360808501826145e8565b50614a6160048501546149d2565b614a6e60a08501826145e8565b506005840154614a8a60c085016001600160a01b0383166145e8565b614a9e60e0850160ff8360a01c1615159052565b506006840154610100840152600790930192610120909201916001016149fa565b6001600160a01b03958616815293909416602084015260408301919091526060820152608081019190915260a00190565b6001600160a01b03929092168252602082015260400190565b5f60208284031215614b19575f5ffd5b815180151581146111f3575f5ffd5b6001600160a01b039390931683526020830191909152604082015260600190565b634e487b7160e01b5f52604160045260245ffd5b5f5f60408385031215614b6e575f5ffd5b505080516020909101519092909150565b5f82614b9957634e487b7160e01b5f52601260045260245ffd5b500490565b8181038181111561080957610809614935565b5f60018201614bc257614bc2614935565b5060010190565b6001600160a01b038481168252831660208083019190915260606040830181905283549083018190525f848152918220906080840190835b81811015614c285783546001600160a01b0316835260019384019360209093019201614c01565b5090979650505050505050565b5f5f60408385031215614c46575f5ffd5b8251614c51816145aa565b6020840151909250614787816145aa565b6001600160a01b03858116825284166020808301919091526040820184905260806060830181905283519083018190525f9184019060a0840190835b81811015614cc55783516001600160a01b0316835260209384019390920191600101614c9e565b509098975050505050505050565b808202811582820484141761080957610809614935565b958652602086019490945260408501929092526001600160a01b03908116606085015216608083015260a082015260c00190565b93845260208401929092526001600160a01b03166040830152606082015260800190565b6001600160a01b0393841681529183166020830152909116604082015260600190565b5f60208284031215614d75575f5ffd5b81516001600160401b03811115614d8a575f5ffd5b8201601f81018413614d9a575f5ffd5b80516001600160401b03811115614db357614db3614b49565b604051600582901b90603f8201601f191681016001600160401b0381118282101715614de157614de1614b49565b604052918252602081840181019290810187841115614dfe575f5ffd5b6020850194505b83851015614e2457614e16856148f3565b815260209485019401614e05565b509695505050505050565b60c08101614e3d828961465b565b614e4a602083018861466f565b6001600160a01b039586166040830152939094166060850152608084019190915260a0909201919091529291505056fe4273856ca27b03e758cdfc9b3b6ca37d494ecb75fbae628757965b75fb104ab6240ac4b1276638a07697a276a1e769aeeef6a875321508eee58718c790a0eb25000000000000000000000000d3397b405a2272f5c27fc673be20579f22f59d6cf7d7115427aac464a6917f7ba3066179fd0c845521f577e53e8e4d4ec97dd4a8799663458a5ef2936f7fa0c99b3336c69c25890f82974f04e811e5bb359186c7000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27c24cdf2085ca2e96c74f42d25648701f34a19b69bce82381dffcf6d00a8dcad5a164736f6c634300081f000a