ETH Price: $3,381.43 (+3.13%)

Token

Guardian Token (Guardian)
 

Overview

Max Total Supply

100,000,000,000,000 Guardian

Holders

394 (0.00%)

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Filtered by Token Holder
Guardian Token: Guardian Token
Balance
451,146,539.706817047719102915 Guardian

Value
$0.00
0x16c525c7cd751c19adf26f39118154d7c4bd0088
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

The Guardian Platform is a dynamic collection of fully integrated resources, utility, and information designed to provide the cryptocurrency and digital asset industry with a user-centric solution portal.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Guardian

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 1 : guardian.sol
// Sources flattened with hardhat v2.8.3 https://hardhat.org

// File @openzeppelin/contracts/utils/[email protected]

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

pragma solidity ^0.8.0;

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

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


// File @openzeppelin/contracts/access/[email protected]
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

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

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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

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


// File @openzeppelin/contracts/token/ERC20/[email protected]
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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


// File @uniswap/v2-core/contracts/interfaces/[email protected]

pragma solidity >=0.5.0;

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

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

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

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

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


// File @uniswap/v2-core/contracts/interfaces/[email protected]

pragma solidity >=0.5.0;

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


// File @uniswap/v2-periphery/contracts/interfaces/[email protected]

pragma solidity >=0.6.2;

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

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

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


// File @uniswap/v2-periphery/contracts/interfaces/[email protected]

pragma solidity >=0.6.2;

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


// File contracts/Guardian.sol

pragma solidity ^0.8.2;



// (Uni|Pancake)Swap libs are interchangeable




/*
    For lines that are marked ERC20 Token Standard, learn more at https://eips.ethereum.org/EIPS/eip-20. 
*/
contract ExtendedReflections is Context, IERC20, Ownable {

    // Keeps track of balances for address that are included in receiving reward.
    mapping (address => uint256) private _reflectionBalances;

    // Keeps track of balances for address that are excluded from receiving reward.
    mapping (address => uint256) private _tokenBalances;

    // Keeps track of which address are excluded from fee.
    mapping (address => bool) private _isExcludedFromFee;

    // Keeps track of which address are excluded from reward.
    mapping (address => bool) private _isExcludedFromReward;
    
    // An array of addresses that are excluded from reward.
    address[] private _excludedFromReward;

    // ERC20 Token Standard
    mapping (address => mapping (address => uint256)) private _allowances;

    // Liquidity pool provider router
    IUniswapV2Router02 internal _uniswapV2Router;

    // This Token and WETH pair contract address.
    address internal _uniswapV2Pair;

    // Where burnt tokens are sent to. This is an address that no one can have accesses to.
    address private constant burnAccount = 0x000000000000000000000000000000000000dEaD;

    address public marketingAddress;
    
    /*
        Tax rate = (_taxXXX / 10**_tax_XXXDecimals) percent.
        For example: if _taxBurn is 1 and _taxBurnDecimals is 2.
        Tax rate = 0.01%

        If you want tax rate for burn to be 5% for example,
        set _taxBurn to 5 and _taxBurnDecimals to 0.
        5 * (10 ** 0) = 5
    */

    // Decimals of taxBurn. Used for have tax less than 1%.
    uint32 private _taxBurnDecimals;

    // Decimals of taxReward. Used for have tax less than 1%.
    uint32 private _taxRewardDecimals;

    // Decimals of taxMarketing. Used for have tax less than 1%.
    uint32 private _taxMarketingDecimals;

    // This percent of a transaction will be burnt.
    uint32 private _taxBurn;

    // This percent of a transaction will be redistribute to all holders.
    uint32 private _taxReward;

    // This percent of a transaction will be transferred to Marketing wallet.
    uint32 private _taxMarketing; 

    // ERC20 Token Standard
    uint32 private _decimals;

    // ERC20 Token Standard
    uint256 private _totalSupply;

    // Current supply:= total supply - burnt tokens
    uint256 private _currentSupply;

    // A number that helps distributing fees to all holders respectively.
    uint256 private _reflectionTotal;

    // Total amount of tokens rewarded / distributing. 
    uint256 private _totalRewarded;

    // Total amount of tokens burnt.
    uint256 private _totalBurnt;

    // A threshold for swap.
    uint256 private _minTokensBeforeSwap;

    // ERC20 Token Standard
    string private _name;
    // ERC20 Token Standard
    string private _symbol;

    // Whether a previous call of swap process is still in process.
    bool private _inSwap;

    bool private _autoBurnEnabled;
    bool private _rewardEnabled;
    bool private _marketingRewardEnabled;
    
    // Prevent reentrancy.
    modifier lockTheSwap {
        require(!_inSwap, "Currently in swap.");
        _inSwap = true;
        _;
        _inSwap = false;
    }

    // Return values of _getValues function.
    struct ValuesFromAmount {
        // Amount of tokens for to transfer.
        uint256 amount;
        // Amount tokens charged for burning.
        uint256 tBurnFee;
        // Amount tokens charged to reward.
        uint256 tRewardFee;

        uint256 tMarketingFee;
        // Amount tokens after fees.
        uint256 tTransferAmount;


        // Reflection of amount.
        uint256 rAmount;
        // Reflection of burn fee.
        uint256 rBurnFee;
        // Reflection of reward fee.
        uint256 rRewardFee;

        uint256 rMarketingFee;
        // Reflection of transfer amount.
        uint256 rTransferAmount;
    }

    /*
        Events
    */
    event Burn(address from, uint256 amount);
    event MinTokensBeforeSwapUpdated(uint256 previous, uint256 current);
    event MarketingAddressUpdated(address previous, address current);
    event AMMPairUpdated(address pair, bool value);
    event ExcludeAccountFromReward(address account);
    event IncludeAccountInReward(address account);
    event ExcludeAccountFromFee(address account);
    event IncludeAccountInFee(address account);
    event EnabledAutoBurn();
    event EnabledReward();
    event EnabledMarketingReward();
    event DisabledAutoBurn();
    event DisabledReward();
    event DisabledMarketingReward();
    event Airdrop(uint256 amount);
    
    constructor (string memory name_, string memory symbol_, uint32 decimals_, uint256 tokenSupply_) {
        // Sets the values for `name`, `symbol`, `totalSupply`, `currentSupply`, and `rTotal`.
        _name = name_;
        _symbol = symbol_;
        _decimals = decimals_;
        _totalSupply = tokenSupply_ * (10 ** decimals_);
        _currentSupply = _totalSupply;
        _reflectionTotal = (~uint256(0) - (~uint256(0) % _totalSupply));

        // Mint
        _reflectionBalances[_msgSender()] = _reflectionTotal;

        // exclude owner and this contract from fee.
        excludeAccountFromFee(owner());
        excludeAccountFromFee(address(this));

        // exclude owner, burnAccount, and this contract from receiving rewards.
        excludeAccountFromReward(owner());
        excludeAccountFromReward(burnAccount);
        excludeAccountFromReward(address(this));
        
        emit Transfer(address(0), _msgSender(), _totalSupply);
    }

    // allow the contract to receive ETH
    receive() external payable {}

    /**
     * @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`).
     *
     * 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 (uint32) {
        return _decimals;
    }

    /**
     * @dev Returns the address of this token and WETH pair.
     */
    function uniswapV2Pair() public view virtual returns (address) {
        return _uniswapV2Pair;
    }

    /**
     * @dev Returns the current burn tax decimals.
     */
    function taxBurnDecimals() public view virtual returns (uint32) {
        return _taxBurnDecimals;
    }

    /**
     * @dev Returns the current reward tax decimals.
     */
    function taxRewardDecimals() public view virtual returns (uint32) {
        return _taxRewardDecimals;
    }

    /**
     * @dev Returns the current marketing tax decimals.
     */
    function taxMarketingDecimals() public view virtual returns (uint32) {
        return _taxMarketingDecimals;
    }

    /**
     * @dev Returns the current burn tax.
     */
    function taxBurn() public view virtual returns (uint32) {
        return _taxBurn;
    }

    /**
     * @dev Returns the current reward tax.
     */
    function taxReward() public view virtual returns (uint32) {
        return _taxReward;
    }

    /**
     * @dev Returns the current marketing tax.
     */
    function taxMarketing() public view virtual returns (uint32) {
        return _taxMarketing;
    }

     /**
     * @dev Returns true if auto burn feature is enabled.
     */
    function autoBurnEnabled() public view virtual returns (bool) {
        return _autoBurnEnabled;
    }

    /**
     * @dev Returns true if reward feature is enabled.
     */
    function rewardEnabled() public view virtual returns (bool) {
        return _rewardEnabled;
    }

    function marketingRewardEnabled() public view virtual returns (bool) {
        return _marketingRewardEnabled;
    }

    /**
     * @dev Returns the threshold before swap.
     */
    function minTokensBeforeSwap() external view virtual returns (uint256) {
        return _minTokensBeforeSwap;
    }

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

    /**
     * @dev Returns current supply of the token. 
     * (currentSupply := totalSupply - totalBurnt)
     */
    function currentSupply() external view virtual returns (uint256) {
        return _currentSupply;
    }

    /**
     * @dev Returns the total number of tokens burnt. 
     */
    function totalBurnt() external view virtual returns (uint256) {
        return _totalBurnt;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        if (_isExcludedFromReward[account]) return _tokenBalances[account];
        return tokenFromReflection(_reflectionBalances[account]);
    }

    /**
     * @dev Returns whether an account is excluded from reward. 
     */
    function isExcludedFromReward(address account) external view returns (bool) {
        return _isExcludedFromReward[account];
    }

    /**
     * @dev Returns whether an account is excluded from fee. 
     */
    function isExcludedFromFee(address account) external view returns (bool) {
        return _isExcludedFromFee[account];
    }

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

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

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        require(_allowances[sender][_msgSender()] >= amount, "ERC20: transfer amount exceeds allowance");
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()] - amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        return true;
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Burn} event indicating the amount burnt.
     * Emits a {Transfer} event with `to` set to the burn address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != burnAccount, "ERC20: burn from the burn address");

        uint256 accountBalance = balanceOf(account);
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");

        uint256 rAmount = _getRAmount(amount);

        // Transfer from account to the burnAccount
        if (_isExcludedFromReward[account]) {
            _tokenBalances[account] -= amount;
        } 
        _reflectionBalances[account] -= rAmount;

        _tokenBalances[burnAccount] += amount;
        _reflectionBalances[burnAccount] += rAmount;

        _currentSupply -= amount;

        _totalBurnt += amount;

        emit Burn(account, amount);
        emit Transfer(account, burnAccount, amount);
    }
    
    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
     *
     * This is 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.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

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

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");
        require(balanceOf(sender) >= amount, "ERC20: transfer amount exceeds balance");

        require(!isBlacklisted[sender] && !isBlacklisted[recipient], "Blacklisted address");

        if (sender != owner() && recipient != owner())
            _beforeTokenTransfer(sender);

        bool buying = false;

        if (AMMPairs[sender]) {
            buying = true;
        }

        bool selling = false;

        if (AMMPairs[recipient]) {
            selling = true;
        }

        ValuesFromAmount memory values = _getValues(amount, !(!_isExcludedFromFee[sender] || (buying && !_isExcludedFromFee[recipient])), selling, buying);

        if (_isExcludedFromReward[sender] && !_isExcludedFromReward[recipient]) {
            _transferFromExcluded(sender, recipient, values);
        } else if (!_isExcludedFromReward[sender] && _isExcludedFromReward[recipient]) {
            _transferToExcluded(sender, recipient, values);
        } else if (!_isExcludedFromReward[sender] && !_isExcludedFromReward[recipient]) {
            _transferStandard(sender, recipient, values);
        } else if (_isExcludedFromReward[sender] && _isExcludedFromReward[recipient]) {
            _transferBothExcluded(sender, recipient, values);
        } else {
            _transferStandard(sender, recipient, values);
        }

        emit Transfer(sender, recipient, values.tTransferAmount);

        if (!_isExcludedFromFee[sender] || (buying && !_isExcludedFromFee[recipient])) {
            _afterTokenTransfer(values);
        }
    }

    function _beforeTokenTransfer(address sender) internal virtual {
        if (_marketingRewardEnabled) {
            uint256 contractBalance = _tokenBalances[address(this)];

            // whether the current contract balances makes the threshold to swap and liquify.
            bool overMinTokensBeforeSwap = contractBalance >= _minTokensBeforeSwap;

            if (overMinTokensBeforeSwap &&
                !_inSwap &&
                !AMMPairs[sender]
                ) 
            {
                sendFeeToAddress(marketingAddress, contractBalance);
            }
        }
    }

    /**
      * @dev Performs all the functionalities that are enabled.
      */
    function _afterTokenTransfer(ValuesFromAmount memory values) internal virtual {
        // Burn
        if (_autoBurnEnabled) {
            _tokenBalances[address(this)] += values.tBurnFee;
            _reflectionBalances[address(this)] += values.rBurnFee;
            _approve(address(this), _msgSender(), values.tBurnFee);
            burnFrom(address(this), values.tBurnFee);
        }   
        
        // Marketing Reward
        if (_marketingRewardEnabled) {
            _tokenBalances[address(this)] += values.tMarketingFee;
            _reflectionBalances[address(this)] += values.rMarketingFee;
        }

        // Reflect
        if (_rewardEnabled) {
            _distributeFee(values.rRewardFee, values.tRewardFee);
        }
    }

    /**
     * @dev Performs transfer between two accounts that are both included in receiving reward.
     */
    function _transferStandard(address sender, address recipient, ValuesFromAmount memory values) private {
        _reflectionBalances[sender] = _reflectionBalances[sender] - values.rAmount;
        _reflectionBalances[recipient] = _reflectionBalances[recipient] + values.rTransferAmount;
    }

    /**
     * @dev Performs transfer from an included account to an excluded account.
     * (included and excluded from receiving reward.)
     */
    function _transferToExcluded(address sender, address recipient, ValuesFromAmount memory values) private {
        _reflectionBalances[sender] = _reflectionBalances[sender] - values.rAmount;
        _tokenBalances[recipient] = _tokenBalances[recipient] + values.tTransferAmount;
        _reflectionBalances[recipient] = _reflectionBalances[recipient] + values.rTransferAmount;
    }

    /**
     * @dev Performs transfer from an excluded account to an included account.
     * (included and excluded from receiving reward.)
     */
    function _transferFromExcluded(address sender, address recipient, ValuesFromAmount memory values) private {
        _tokenBalances[sender] = _tokenBalances[sender] - values.amount;
        _reflectionBalances[sender] = _reflectionBalances[sender] - values.rAmount;
        _reflectionBalances[recipient] = _reflectionBalances[recipient] + values.rTransferAmount;
    }

    /**
     * @dev Performs transfer between two accounts that are both excluded in receiving reward.
     */
    function _transferBothExcluded(address sender, address recipient, ValuesFromAmount memory values) private {
        _tokenBalances[sender] = _tokenBalances[sender] - values.amount;
        _reflectionBalances[sender] = _reflectionBalances[sender] - values.rAmount;
        _tokenBalances[recipient] = _tokenBalances[recipient] + values.tTransferAmount;
        _reflectionBalances[recipient] = _reflectionBalances[recipient] + values.rTransferAmount;
    }
    
    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

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

    /**
      * @dev Excludes an account from receiving reward.
      *
      * Emits a {ExcludeAccountFromReward} event.
      *
      * Requirements:
      *
      * - `account` is included in receiving reward.
      */
    function excludeAccountFromReward(address account) public onlyOwner {
        require(!_isExcludedFromReward[account], "Account already excluded from reward");
        if(_reflectionBalances[account] > 0) {
            _tokenBalances[account] = tokenFromReflection(_reflectionBalances[account]);
        }
        _isExcludedFromReward[account] = true;
        _excludedFromReward.push(account);
        
        emit ExcludeAccountFromReward(account);
    }

    /**
      * @dev Includes an account from receiving reward.
      *
      * Emits a {IncludeAccountInReward} event.
      *
      * Requirements:
      *
      * - `account` is excluded in receiving reward.
      */
    function includeAccountInReward(address account) public onlyOwner {
        require(_isExcludedFromReward[account], "Account is already included.");

        for (uint256 i = 0; i < _excludedFromReward.length; i++) {
            if (_excludedFromReward[i] == account) {
                _excludedFromReward[i] = _excludedFromReward[_excludedFromReward.length - 1];
                _tokenBalances[account] = 0;
                _isExcludedFromReward[account] = false;
                _excludedFromReward.pop();
                break;
            }
        }

        emit IncludeAccountInReward(account);
    }

     /**
      * @dev Excludes an account from fee.
      *
      * Emits a {ExcludeAccountFromFee} event.
      *
      * Requirements:
      *
      * - `account` is included in fee.
      */
    function excludeAccountFromFee(address account) public onlyOwner {
        _isExcludedFromFee[account] = true;

        emit ExcludeAccountFromFee(account);
    }

    /**
      * @dev Includes an account from fee.
      *
      * Emits a {IncludeAccountFromFee} event.
      *
      * Requirements:
      *
      * - `account` is excluded in fee.
      */
    function includeAccountInFee(address account) public onlyOwner {
        require(_isExcludedFromFee[account], "Account is already included.");

        _isExcludedFromFee[account] = false;
        
        emit IncludeAccountInFee(account);
    }

    /**
     * @dev Airdrop tokens to all holders that are included from reward. 
     *  Requirements:
     * - the caller must have a balance of at least `amount`.
     */
    function airdrop(uint256 amount) public {
        address sender = _msgSender();

        require(balanceOf(sender) >= amount, "The caller must have balance >= amount.");
        ValuesFromAmount memory values = _getValues(amount, false, false, false);
        if (_isExcludedFromReward[sender]) {
            _tokenBalances[sender] -= values.amount;
        }
        _reflectionBalances[sender] -= values.rAmount;
        
        _reflectionTotal = _reflectionTotal - values.rAmount;
        _totalRewarded += amount;
        emit Airdrop(amount);
    }

    /**
     * @dev Returns the reflected amount of a token.
     *  Requirements:
     * - `amount` must be less than total supply.
     */
    function reflectionFromToken(uint256 amount, bool deductTransferFee, bool selling, bool buying) internal view returns(uint256) {
        require(amount <= _totalSupply, "Amount must be less than supply");
        ValuesFromAmount memory values = _getValues(amount, deductTransferFee, selling, buying);
        return values.rTransferAmount;
    }

    /**
     * @dev Used to figure out the balance after reflection.
     * Requirements:
     * - `rAmount` must be less than reflectTotal.
     */
    function tokenFromReflection(uint256 rAmount) internal view returns(uint256) {
        require(rAmount <= _reflectionTotal, "Amount must be less than total reflections");
        uint256 currentRate =  _getRate();
        return rAmount / currentRate;
    }

    function sendFeeToAddress(address _addr, uint256 _tAmount) private {
        swapTokensForEth(_addr, _tAmount);
    }

    /**
     * @dev Swap `amount` tokens for ETH.
     *
     * Emits {Transfer} event. From this contract to the token and WETH Pair.
     */
    function swapTokensForEth(address recipient, uint256 amount) private lockTheSwap {
        // Generate the uniswap pair path of token -> weth
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = _uniswapV2Router.WETH();

        _approve(address(this), address(_uniswapV2Router), amount);

        // Swap tokens to ETH
        _uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            amount, 
            0, 
            path, 
            recipient,
            block.timestamp
        );
    }

    /**
     * @dev Distribute the `tRewardFee` tokens to all holders that are included in receiving reward.
     * amount received is based on how many token one owns.  
     */
    function _distributeFee(uint256 rRewardFee, uint256 tRewardFee) private {
        // This would decrease rate, thus increase amount reward receive based on one's balance.
        _reflectionTotal = _reflectionTotal - rRewardFee;
        _totalRewarded += tRewardFee;
    }
    
    /**
     * @dev Returns fees and transfer amount in both tokens and reflections.
     * tXXXX stands for tokenXXXX
     * rXXXX stands for reflectionXXXX
     * More details can be found at comments for ValuesForAmount Struct.
     */
    function _getValues(uint256 amount, bool deductTransferFee, bool selling, bool buying) private view returns (ValuesFromAmount memory) {
        ValuesFromAmount memory values;
        values.amount = amount;
        _getTValues(values, deductTransferFee, selling, buying);
        _getRValues(values, deductTransferFee);
        return values;
    }

    /**
     * @dev Adds fees and transfer amount in tokens to `values`.
     * tXXXX stands for tokenXXXX
     * More details can be found at comments for ValuesForAmount Struct.
     */
    function _getTValues(ValuesFromAmount memory values, bool deductTransferFee, bool selling, bool buying) view private {
        
        if (deductTransferFee) {
            values.tTransferAmount = values.amount;
        } else {

            if (buying) {
                values.tBurnFee = _calculateTax(values.amount, _taxBurn, _taxBurnDecimals);
                values.tMarketingFee = _calculateTax(values.amount, _taxMarketing, _taxMarketingDecimals);
                values.tRewardFee = _calculateTax(values.amount, _taxReward, _taxRewardDecimals);
            } else if (selling) {
                uint32 totalTax = _taxBurn + _taxMarketing + _taxReward;

                if (totalTax > 0) {
                    values.tBurnFee = _calculateTax(values.amount, _taxBurn * sellTaxIncrease / totalTax, _taxBurnDecimals);
                    values.tMarketingFee = _calculateTax(values.amount, _taxMarketing * sellTaxIncrease / totalTax, _taxMarketingDecimals);
                    values.tRewardFee = _calculateTax(values.amount, _taxReward * sellTaxIncrease / totalTax, _taxRewardDecimals);
                }
            }
            
            // amount after fee
            values.tTransferAmount = values.amount - values.tBurnFee - values.tRewardFee - values.tMarketingFee;
        }
        
    }

    /**
     * @dev Adds fees and transfer amount in reflection to `values`.
     * rXXXX stands for reflectionXXXX
     * More details can be found at comments for ValuesForAmount Struct.
     */
    function _getRValues(ValuesFromAmount memory values, bool deductTransferFee) view private {
        uint256 currentRate = _getRate();

        values.rAmount = values.amount * currentRate;

        if (deductTransferFee) {
            values.rTransferAmount = values.rAmount;
        } else {
            values.rAmount = values.amount * currentRate;

            values.rBurnFee = values.tBurnFee * currentRate;
            values.rMarketingFee = values.tMarketingFee * currentRate;
            values.rRewardFee = values.tRewardFee * currentRate;

            values.rTransferAmount = values.rAmount - values.rBurnFee - values.rRewardFee - values.rMarketingFee;
        }
        
    }

    /**
     * @dev Returns `amount` in reflection.
     */
    function _getRAmount(uint256 amount) private view returns (uint256) {
        uint256 currentRate = _getRate();
        return amount * currentRate;
    }

    /**
     * @dev Returns the current reflection rate.
     */
    function _getRate() private view returns(uint256) {
        (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
        return rSupply / tSupply;
    }

    /**
     * @dev Returns the current reflection supply and token supply.
     */
    function _getCurrentSupply() private view returns(uint256, uint256) {
        uint256 rSupply = _reflectionTotal;
        uint256 tSupply = _totalSupply;      
        for (uint256 i = 0; i < _excludedFromReward.length; i++) {
            if (_reflectionBalances[_excludedFromReward[i]] > rSupply || _tokenBalances[_excludedFromReward[i]] > tSupply) return (_reflectionTotal, _totalSupply);
            rSupply = rSupply - _reflectionBalances[_excludedFromReward[i]];
            tSupply = tSupply - _tokenBalances[_excludedFromReward[i]];
        }
        if (rSupply < _reflectionTotal / _totalSupply) return (_reflectionTotal, _totalSupply);
        return (rSupply, tSupply);
    }

    /**
     * @dev Returns fee based on `amount` and `taxRate`
     */
    function _calculateTax(uint256 amount, uint32 tax, uint32 taxDecimals_) private pure returns (uint256) {
        return amount * tax / (10 ** taxDecimals_) / (10 ** 2);
    }

    /*
        Owner functions
    */

    /**
     * @dev Enables the auto burn feature.
     * Burn transaction amount * `taxBurn_` amount of tokens each transaction when enabled.
     *
     * Emits a {EnabledAutoBurn} event.
     *
     * Requirements:
     *
     * - auto burn feature mush be disabled.
     * - tax must be greater than 0.
     * - tax decimals + 2 must be less than token decimals. 
     * (because tax rate is in percentage)
     */
    function enableAutoBurn(uint32 taxBurn_, uint32 taxBurnDecimals_) public onlyOwner {
        require(!_autoBurnEnabled, "Auto burn feature is already enabled.");
        require(taxBurn_ > 0, "Tax rate must be greater than 0.");
        require(taxBurnDecimals_ + 2  <= decimals(), "Tax decimals must be less than token decimals - 2");
        
        _autoBurnEnabled = true;
        setTaxBurn(taxBurn_, taxBurnDecimals_);
        
        emit EnabledAutoBurn();
    }

    /**
     * @dev Enables the reward feature.
     * Distribute transaction amount * `taxReward_` amount of tokens each transaction when enabled.
     *
     * Emits a {EnabledReward} event.
     *
     * Requirements:
     *
     * - reward feature mush be disabled.
     * - tax must be greater than 0.
     * - tax decimals + 2 must be less than token decimals. 
     * (because tax rate is in percentage)
    */
    function enableReward(uint32 taxReward_, uint32 taxRewardDecimals_) public onlyOwner {
        require(!_rewardEnabled, "Reward feature is already enabled.");
        require(taxReward_ > 0, "Tax rate must be greater than 0.");
        require(taxRewardDecimals_ + 2  <= decimals(), "Tax decimals must be less than token decimals - 2");

        _rewardEnabled = true;
        setTaxReward(taxReward_, taxRewardDecimals_);

        emit EnabledReward();
    }

    function initSwap(address routerAddress_, uint256 minTokensBeforeSwap_) public onlyOwner {
        // init Router
        IUniswapV2Router02 uniswapV2Router = IUniswapV2Router02(routerAddress_);

        _uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).getPair(address(this), uniswapV2Router.WETH());

        if (_uniswapV2Pair == address(0)) {
            _uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory())
                .createPair(address(this), uniswapV2Router.WETH());
        }
        
        _uniswapV2Router = uniswapV2Router;
        _setAMMPair(_uniswapV2Pair, true);

        if (!_isExcludedFromReward[address(uniswapV2Router)])
            excludeAccountFromReward(address(uniswapV2Router));
        excludeAccountFromFee(address(uniswapV2Router));

        setMinTokensBeforeSwap(minTokensBeforeSwap_);
    }

    function enableMarketingTax(uint32 taxMarketing_, uint32 taxMarketingDecimals_, address marketingAddress_) public onlyOwner {
        require(!_marketingRewardEnabled, "Marketing tax feature is already enabled.");
        require(taxMarketing_ > 0, "Tax rate must be greater than 0.");
        require(taxMarketingDecimals_ + 2  <= decimals(), "Tax decimals must be less than token decimals - 2");

        _marketingRewardEnabled = true;
        setMarketingTax(taxMarketing_, taxMarketingDecimals_);
        setMarketingAddress(marketingAddress_);

        emit EnabledMarketingReward();
    }

    /**
     * @dev Disables the auto burn feature.
     *
     * Emits a {DisabledAutoBurn} event.
     *
     * Requirements:
     *
     * - auto burn feature mush be enabled.
     */
    function disableAutoBurn() public onlyOwner {
        require(_autoBurnEnabled, "Auto burn feature is already disabled.");

        setTaxBurn(0, 0);
        _autoBurnEnabled = false;
        
        emit DisabledAutoBurn();
    }

    /**
      * @dev Disables the reward feature.
      *
      * Emits a {DisabledReward} event.
      *
      * Requirements:
      *
      * - reward feature mush be enabled.
      */
    function disableReward() public onlyOwner {
        require(_rewardEnabled, "Reward feature is already disabled.");

        setTaxReward(0, 0);
        _rewardEnabled = false;
        
        emit DisabledReward();
    }


    function disableMarketingTax() public onlyOwner {
        require(_marketingRewardEnabled, "Marketing reward feature is already disabled.");

        setMarketingTax(0, 0);
        setMarketingAddress(address(0x0));
        _marketingRewardEnabled = false;
        
        emit DisabledMarketingReward();
    }

     /**
      * @dev Updates `_minTokensBeforeSwap`
      *
      * Emits a {MinTokensBeforeSwap} event.
      *
      * Requirements:
      *
      * - `minTokensBeforeSwap_` must be less than _currentSupply.
      */
    function setMinTokensBeforeSwap(uint256 minTokensBeforeSwap_) public onlyOwner {
        require(minTokensBeforeSwap_ < _currentSupply, "minTokensBeforeSwap must be lower than current supply.");

        uint256 previous = _minTokensBeforeSwap;
        _minTokensBeforeSwap = minTokensBeforeSwap_;

        emit MinTokensBeforeSwapUpdated(previous, _minTokensBeforeSwap);
    }

    /**
      * @dev Updates taxes
      */
    function setTaxBurn(uint32 taxBurn_, uint32 taxBurnDecimals_) public onlyOwner {
        require(_autoBurnEnabled, "Auto burn feature must be enabled. Try the enableAutoBurn function.");
        require(taxBurn_ + _taxReward + _taxMarketing <= sellTaxIncrease, "Total tax must be lower than sellTaxIncrease");

        _taxBurn = taxBurn_;
        _taxBurnDecimals = taxBurnDecimals_;
    }

    function setTaxReward(uint32 taxReward_, uint32 taxRewardDecimals_) public onlyOwner {
        require(_rewardEnabled, "Reward feature must be enabled. Try the enableReward function.");
        require(_taxBurn + taxReward_ + _taxMarketing <= sellTaxIncrease, "Total tax must be lower than sellTaxIncrease");

        _taxReward = taxReward_;
        _taxRewardDecimals = taxRewardDecimals_;
    }

    function setMarketingTax(uint32 taxMarketing_, uint32 taxMarketingDecimals_) public onlyOwner {
        require(_marketingRewardEnabled, "Marketing reward feature must be enabled. Try the enableMarketingTax function.");
        require(_taxBurn + _taxReward + taxMarketing_ <= sellTaxIncrease, "Total tax must be lower than sellTaxIncrease");

        _taxMarketing = taxMarketing_;
        _taxMarketingDecimals = taxMarketingDecimals_;
    }

    function setMarketingAddress(address marketingAddress_) public onlyOwner {
        address previous = marketingAddress;
        marketingAddress = marketingAddress_;

        if (!_isExcludedFromReward[marketingAddress_])
            excludeAccountFromReward(marketingAddress_);

        excludeAccountFromFee(marketingAddress_);

        emit MarketingAddressUpdated(previous, marketingAddress_);
    }

    // ##############
    // Features added
    // ##############

    uint32 public sellTaxIncrease;

    mapping (address => bool) public AMMPairs;

    mapping(address => bool) public isBlacklisted;

    function setAMMPair(address pair, bool value) public onlyOwner {
        require(pair != _uniswapV2Pair, "The main pair cannot be removed from AMMPairs.");

        _setAMMPair(pair, value);
    }

    function _setAMMPair(address pair, bool value) private {
        AMMPairs[pair] = value;

        if(value) {
            if (!_isExcludedFromReward[pair])
                excludeAccountFromReward(pair);

            excludeAccountFromFee(pair);
        }

        emit AMMPairUpdated(pair, value);
    }

    function changeSellTaxIncrease(uint32 amount) public onlyOwner {
        require(amount >= (_taxBurn + _taxReward + _taxMarketing) && amount <= 25, "Tax rate must be greater than total buy tax and lower than 25.");

        sellTaxIncrease = amount;
    }

    function blacklistAccount(address account, bool value) external onlyOwner {
        isBlacklisted[account] = value;
    }
}

contract Guardian is ExtendedReflections {

    uint256 private _tokenSupply = 100_000_000_000_000;

    uint32 private _taxBurn = 1;
    uint32 private _taxReward = 2;
    uint32 private _taxMarketing = 6;

    uint32 private _sellTaxIncrease = 25;

    uint32 private _taxDecimals = 0;
    uint32 private _decimals = 18;

    uint256 private _minTokensBeforeSwap = 100_000_000 * (10 ** _decimals);

    address private _routerAddress = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
    address private _marketingAddress = 0xd9deAC4Fa2cAc6871072a186F868EB305CdbCCA1;

    constructor () ExtendedReflections("Guardian Token", "Guardian", _decimals, _tokenSupply) {
        changeSellTaxIncrease(_sellTaxIncrease);

        enableAutoBurn(_taxBurn, _taxDecimals);
        enableReward(_taxReward, _taxDecimals);
        enableMarketingTax(_taxMarketing, _taxDecimals, _marketingAddress);

        initSwap(_routerAddress, _minTokensBeforeSwap);
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"bool","name":"value","type":"bool"}],"name":"AMMPairUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Airdrop","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[],"name":"DisabledAutoBurn","type":"event"},{"anonymous":false,"inputs":[],"name":"DisabledMarketingReward","type":"event"},{"anonymous":false,"inputs":[],"name":"DisabledReward","type":"event"},{"anonymous":false,"inputs":[],"name":"EnabledAutoBurn","type":"event"},{"anonymous":false,"inputs":[],"name":"EnabledMarketingReward","type":"event"},{"anonymous":false,"inputs":[],"name":"EnabledReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"ExcludeAccountFromFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"ExcludeAccountFromReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"IncludeAccountInFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"IncludeAccountInReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previous","type":"address"},{"indexed":false,"internalType":"address","name":"current","type":"address"}],"name":"MarketingAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"previous","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"current","type":"uint256"}],"name":"MinTokensBeforeSwapUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"AMMPairs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"autoBurnEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"blacklistAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"name":"changeSellTaxIncrease","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableAutoBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableMarketingTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"taxBurn_","type":"uint32"},{"internalType":"uint32","name":"taxBurnDecimals_","type":"uint32"}],"name":"enableAutoBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"taxMarketing_","type":"uint32"},{"internalType":"uint32","name":"taxMarketingDecimals_","type":"uint32"},{"internalType":"address","name":"marketingAddress_","type":"address"}],"name":"enableMarketingTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"taxReward_","type":"uint32"},{"internalType":"uint32","name":"taxRewardDecimals_","type":"uint32"}],"name":"enableReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeAccountFromFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"excludeAccountFromReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"includeAccountInFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"includeAccountInReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"routerAddress_","type":"address"},{"internalType":"uint256","name":"minTokensBeforeSwap_","type":"uint256"}],"name":"initSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketingAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketingRewardEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minTokensBeforeSwap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellTaxIncrease","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"setAMMPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"marketingAddress_","type":"address"}],"name":"setMarketingAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"taxMarketing_","type":"uint32"},{"internalType":"uint32","name":"taxMarketingDecimals_","type":"uint32"}],"name":"setMarketingTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minTokensBeforeSwap_","type":"uint256"}],"name":"setMinTokensBeforeSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"taxBurn_","type":"uint32"},{"internalType":"uint32","name":"taxBurnDecimals_","type":"uint32"}],"name":"setTaxBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"taxReward_","type":"uint32"},{"internalType":"uint32","name":"taxRewardDecimals_","type":"uint32"}],"name":"setTaxReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxBurn","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxBurnDecimals","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxMarketing","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxMarketingDecimals","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxReward","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxRewardDecimals","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBurnt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV2Pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080604052655af3107a4000601655601780546001600160c01b031916741200000000000000190000000600000002000000011790819055620000529063ffffffff600160a01b90910416600a62001bff565b62000062906305f5e10062001cc3565b601855601980546001600160a01b0319908116737a250d5630b4cf539739df2c5dacb4c659f2488d17909155601a805490911673d9deac4fa2cac6871072a186f868eb305cdbcca1179055348015620000ba57600080fd5b506040518060400160405280600e81526020016d23bab0b93234b0b7102a37b5b2b760911b8152506040518060400160405280600881526020016723bab0b93234b0b760c11b815250601760149054906101000a900463ffffffff16601654620001336200012d6200033460201b60201c565b62000338565b83516200014890601190602087019062001aa3565b5082516200015e90601290602086019062001aa3565b50600a805463ffffffff60601b19166c0100000000000000000000000063ffffffff8516021781556200019390839062001bff565b6200019f908262001cc3565b600b819055600c819055620001b79060001962001d5a565b620001c59060001962001ce5565b600d8190553360009081526001602052604081209190915554620001f2906001600160a01b031662000388565b620001fd3062000388565b6200021a620002146000546001600160a01b031690565b62000432565b6200022761dead62000432565b620002323062000432565b600b5460405190815233906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a350506017546200029692506c01000000000000000000000000900463ffffffff169050620005e8565b601754620002b59063ffffffff80821691600160801b9004166200072b565b601754620002db9063ffffffff6401000000008204811691600160801b900416620008ff565b601754601a54620003139163ffffffff680100000000000000008204811692600160801b90920416906001600160a01b031662000ad3565b6019546018546200032e916001600160a01b03169062000cbd565b62001db3565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b03163314620003d75760405162461bcd60e51b8152602060048201819052602482015260008051602062005fba83398151915260448201526064015b60405180910390fd5b6001600160a01b038116600081815260036020908152604091829020805460ff1916600117905590519182527f7e35d6b74d35c333860340884eeca4e63b18cb9d73ce17a147a1952654365b5e91015b60405180910390a150565b6000546001600160a01b031633146200047d5760405162461bcd60e51b8152602060048201819052602482015260008051602062005fba8339815191526044820152606401620003ce565b6001600160a01b03811660009081526004602052604090205460ff1615620004f45760405162461bcd60e51b8152602060048201526024808201527f4163636f756e7420616c7265616479206578636c756465642066726f6d2072656044820152631dd85c9960e21b6064820152608401620003ce565b6001600160a01b0381166000908152600160205260409020541562000551576001600160a01b0381166000908152600160205260409020546200053790620010c2565b6001600160a01b0382166000908152600260205260409020555b6001600160a01b0381166000818152600460209081526040808320805460ff191660019081179091556005805491820181559093527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db090920180546001600160a01b0319168417905590519182527fd29a806ac7ba79249e665eb27435d70121361773ea7475dfedd53faf9537782f910162000427565b6000546001600160a01b03163314620006335760405162461bcd60e51b8152602060048201819052602482015260008051602062005fba8339815191526044820152606401620003ce565b600a5463ffffffff680100000000000000008204811691620006619164010000000082048116911662001b74565b6200066d919062001b74565b63ffffffff168163ffffffff161015801562000690575060198163ffffffff1611155b620007045760405162461bcd60e51b815260206004820152603e60248201527f5461782072617465206d7573742062652067726561746572207468616e20746f60448201527f74616c206275792074617820616e64206c6f776572207468616e2032352e00006064820152608401620003ce565b6013805463ffffffff9092166401000000000263ffffffff60201b19909216919091179055565b6000546001600160a01b03163314620007765760405162461bcd60e51b8152602060048201819052602482015260008051602062005fba8339815191526044820152606401620003ce565b601354610100900460ff1615620007de5760405162461bcd60e51b815260206004820152602560248201527f4175746f206275726e206665617475726520697320616c726561647920656e61604482015264313632b21760d91b6064820152608401620003ce565b60008263ffffffff1611620008255760405162461bcd60e51b8152602060048201819052602482015260008051602062005f7a8339815191526044820152606401620003ce565b62000845600a546c01000000000000000000000000900463ffffffff1690565b63ffffffff166200085882600262001b74565b63ffffffff161115620008b75760405162461bcd60e51b8152602060048201526031602482015260008051602062005f5a83398151915260448201527037b5b2b7103232b1b4b6b0b6399016901960791b6064820152608401620003ce565b6013805461ff001916610100179055620008d282826200114c565b6040517f1ae0c73021a2d0e597101e249754f53e8496443b3820ba2128b562a9873ad0b190600090a15050565b6000546001600160a01b031633146200094a5760405162461bcd60e51b8152602060048201819052602482015260008051602062005fba8339815191526044820152606401620003ce565b60135462010000900460ff1615620009b05760405162461bcd60e51b815260206004820152602260248201527f526577617264206665617475726520697320616c726561647920656e61626c65604482015261321760f11b6064820152608401620003ce565b60008263ffffffff1611620009f75760405162461bcd60e51b8152602060048201819052602482015260008051602062005f7a8339815191526044820152606401620003ce565b62000a17600a546c01000000000000000000000000900463ffffffff1690565b63ffffffff1662000a2a82600262001b74565b63ffffffff16111562000a895760405162461bcd60e51b8152602060048201526031602482015260008051602062005f5a83398151915260448201527037b5b2b7103232b1b4b6b0b6399016901960791b6064820152608401620003ce565b6013805462ff000019166201000017905562000aa68282620012f6565b6040517fba4445e1bffa6a2c7f9686f9082addd1cbaf92d402889b0c26dcc2aa101f658e90600090a15050565b6000546001600160a01b0316331462000b1e5760405162461bcd60e51b8152602060048201819052602482015260008051602062005fba8339815191526044820152606401620003ce565b6013546301000000900460ff161562000b8c5760405162461bcd60e51b815260206004820152602960248201527f4d61726b6574696e6720746178206665617475726520697320616c72656164796044820152681032b730b13632b21760b91b6064820152608401620003ce565b60008363ffffffff161162000bd35760405162461bcd60e51b8152602060048201819052602482015260008051602062005f7a8339815191526044820152606401620003ce565b62000bf3600a546c01000000000000000000000000900463ffffffff1690565b63ffffffff1662000c0683600262001b74565b63ffffffff16111562000c655760405162461bcd60e51b8152602060048201526031602482015260008051602062005f5a83398151915260448201527037b5b2b7103232b1b4b6b0b6399016901960791b6064820152608401620003ce565b6013805463ff0000001916630100000017905562000c8483836200149c565b62000c8f8162001655565b6040517fdff025d7b2c180bfe5a540637f1772af5b3b0b67452af47016be16ea128a58e190600090a1505050565b6000546001600160a01b0316331462000d085760405162461bcd60e51b8152602060048201819052602482015260008051602062005fba8339815191526044820152606401620003ce565b6000829050806001600160a01b031663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b15801562000d4757600080fd5b505afa15801562000d5c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d82919062001b49565b6001600160a01b031663e6a4390530836001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b15801562000dcb57600080fd5b505afa15801562000de0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e06919062001b49565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260440160206040518083038186803b15801562000e4d57600080fd5b505afa15801562000e62573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e88919062001b49565b600880546001600160a01b0319166001600160a01b039290921691821790556200104a57806001600160a01b031663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b15801562000ee657600080fd5b505afa15801562000efb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f21919062001b49565b6001600160a01b031663c9c6539630836001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b15801562000f6a57600080fd5b505afa15801562000f7f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000fa5919062001b49565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381600087803b15801562000fee57600080fd5b505af115801562001003573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001029919062001b49565b600880546001600160a01b0319166001600160a01b03929092169190911790555b600780546001600160a01b0319166001600160a01b03838116919091179091556008546200107b9116600162001738565b6001600160a01b03811660009081526004602052604090205460ff16620010a757620010a78162000432565b620010b28162000388565b620010bd82620017de565b505050565b6000600d548211156200112b5760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e74206d757374206265206c657373207468616e20746f74616c207260448201526965666c656374696f6e7360b01b6064820152608401620003ce565b600062001137620018e1565b905062001145818462001b9f565b9392505050565b6000546001600160a01b03163314620011975760405162461bcd60e51b8152602060048201819052602482015260008051602062005fba8339815191526044820152606401620003ce565b601354610100900460ff16620012225760405162461bcd60e51b815260206004820152604360248201527f4175746f206275726e2066656174757265206d75737420626520656e61626c6560448201527f642e205472792074686520656e61626c654175746f4275726e2066756e63746960648201526237b71760e91b608482015260a401620003ce565b601354600a5463ffffffff640100000000928390048116926801000000000000000083048216926200125992919004168562001b74565b62001265919062001b74565b63ffffffff161115620012bf5760405162461bcd60e51b815260206004820152602c602482015260008051602062005f9a83398151915260448201526b6c546178496e63726561736560a01b6064820152608401620003ce565b600a805463ffffffff93841663ffffffff199091161790556009805491909216600160a01b0263ffffffff60a01b19909116179055565b6000546001600160a01b03163314620013415760405162461bcd60e51b8152602060048201819052602482015260008051602062005fba8339815191526044820152606401620003ce565b60135462010000900460ff16620013c15760405162461bcd60e51b815260206004820152603e60248201527f5265776172642066656174757265206d75737420626520656e61626c65642e2060448201527f5472792074686520656e61626c655265776172642066756e6374696f6e2e00006064820152608401620003ce565b601354600a5463ffffffff640100000000909204821691680100000000000000008204811691620013f59186911662001b74565b62001401919062001b74565b63ffffffff1611156200145b5760405162461bcd60e51b815260206004820152602c602482015260008051602062005f9a83398151915260448201526b6c546178496e63726561736560a01b6064820152608401620003ce565b600a805463ffffffff9384166401000000000263ffffffff60201b199091161790556009805491909216600160c01b0263ffffffff60c01b19909116179055565b6000546001600160a01b03163314620014e75760405162461bcd60e51b8152602060048201819052602482015260008051602062005fba8339815191526044820152606401620003ce565b6013546301000000900460ff166200157f5760405162461bcd60e51b815260206004820152604e60248201527f4d61726b6574696e67207265776172642066656174757265206d75737420626560448201527f20656e61626c65642e205472792074686520656e61626c654d61726b6574696e60648201526d33aa30bc10333ab731ba34b7b71760911b608482015260a401620003ce565b601354600a5463ffffffff640100000000928390048116928592620015ab929181048216911662001b74565b620015b7919062001b74565b63ffffffff161115620016115760405162461bcd60e51b815260206004820152602c602482015260008051602062005f9a83398151915260448201526b6c546178496e63726561736560a01b6064820152608401620003ce565b600a805463ffffffff938416680100000000000000000263ffffffff60401b199091161790556009805491909216600160e01b026001600160e01b03909116179055565b6000546001600160a01b03163314620016a05760405162461bcd60e51b8152602060048201819052602482015260008051602062005fba8339815191526044820152606401620003ce565b600980546001600160a01b038381166001600160a01b0319831681179093556000928352600460205260409092205491169060ff16620016e557620016e58262000432565b620016f08262000388565b604080516001600160a01b038084168252841660208201527fa8efc72ed34f90017df79620d1972d42b8e3b17eb0077fc5fc46cbf1a19ed9a991015b60405180910390a15050565b6001600160a01b0382166000908152601460205260409020805460ff191682158015919091179091556200179d576001600160a01b03821660009081526004602052604090205460ff166200179257620017928262000432565b6200179d8262000388565b604080516001600160a01b038416815282151560208201527f9a05f836a81b64d2d3ee62b752e87947ab26a9fdcd5b2572b1744ae8499b3aac91016200172c565b6000546001600160a01b03163314620018295760405162461bcd60e51b8152602060048201819052602482015260008051602062005fba8339815191526044820152606401620003ce565b600c548110620018a25760405162461bcd60e51b815260206004820152603660248201527f6d696e546f6b656e734265666f726553776170206d757374206265206c6f776560448201527f72207468616e2063757272656e7420737570706c792e000000000000000000006064820152608401620003ce565b601080549082905560408051828152602081018490527fd2f58a5c369e86bc74f3b5be6f9a34224ebb43d603f7acee04b07ef21c7d14bf91016200172c565b60008080620018ef62001907565b909250905062001900818362001b9f565b9250505090565b600d54600b546000918291825b60055481101562001a6f578260016000600584815481106200193a576200193a62001d9d565b60009182526020808320909101546001600160a01b031683528201929092526040019020541180620019a9575081600260006005848154811062001982576200198262001d9d565b60009182526020808320909101546001600160a01b03168352820192909252604001902054115b15620019c057600d54600b54945094505050509091565b6001600060058381548110620019da57620019da62001d9d565b60009182526020808320909101546001600160a01b0316835282019290925260400190205462001a0b908462001ce5565b9250600260006005838154811062001a275762001a2762001d9d565b60009182526020808320909101546001600160a01b0316835282019290925260400190205462001a58908362001ce5565b91508062001a668162001d3c565b91505062001914565b50600b54600d5462001a82919062001b9f565b82101562001a9a57600d54600b549350935050509091565b90939092509050565b82805462001ab19062001cff565b90600052602060002090601f01602090048101928262001ad5576000855562001b20565b82601f1062001af057805160ff191683800117855562001b20565b8280016001018555821562001b20579182015b8281111562001b2057825182559160200191906001019062001b03565b5062001b2e92915062001b32565b5090565b5b8082111562001b2e576000815560010162001b33565b60006020828403121562001b5c57600080fd5b81516001600160a01b03811681146200114557600080fd5b600063ffffffff80831681851680830382111562001b965762001b9662001d71565b01949350505050565b60008262001bb15762001bb162001d87565b500490565b600181815b8085111562001bf757816000190482111562001bdb5762001bdb62001d71565b8085161562001be957918102915b93841c939080029062001bbb565b509250929050565b60006200114563ffffffff84168360008262001c1e5750600162001cbd565b8162001c2d5750600062001cbd565b816001811462001c46576002811462001c515762001c71565b600191505062001cbd565b60ff84111562001c655762001c6562001d71565b50506001821b62001cbd565b5060208310610133831016604e8410600b841016171562001c96575081810a62001cbd565b62001ca2838362001bb6565b806000190482111562001cb95762001cb962001d71565b0290505b92915050565b600081600019048311821515161562001ce05762001ce062001d71565b500290565b60008282101562001cfa5762001cfa62001d71565b500390565b600181811c9082168062001d1457607f821691505b6020821081141562001d3657634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141562001d535762001d5362001d71565b5060010190565b60008262001d6c5762001d6c62001d87565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6141978062001dc36000396000f3fe6080604052600436106103545760003560e01c806379cc6790116101c6578063aa5e8752116100f7578063daa9334111610095578063e5d41c6b1161006f578063e5d41c6b14610a17578063f2fde38b14610a2c578063fbfa089c14610a4c578063fe575a8714610a6e57600080fd5b8063daa933411461098f578063dd62ed3e146109af578063e2314bea146109f557600080fd5b8063becc01e4116100d1578063becc01e414610909578063c08a95f11461092d578063d42ac3771461094d578063d6b4212b1461096f57600080fd5b8063aa5e8752146108a7578063ad8e91dd146108c7578063af1d8554146108e957600080fd5b806395d89b41116101645780639dd255da1161013e5780639dd255da1461082a578063a457c2d714610847578063a5ece94114610867578063a9059cbb1461088757600080fd5b806395d89b41146107e0578063966ff650146107f557806397dc4a131461080a57600080fd5b806388f82020116101a057806388f82020146107495780638da5cb5b14610782578063906e9dd0146107a057806390c364b2146107c057600080fd5b806379cc6790146106e95780638397295114610709578063882f86d61461072957600080fd5b8063313ce567116102a05780636049876e1161023e578063715018a611610218578063715018a61461067a5780637656e1461461068f57806376856557146106a4578063771282f6146106d457600080fd5b80636049876e1461061a57806368349f491461063a57806370a082311461065a57600080fd5b8063470d5cbd1161027a578063470d5cbd1461057a57806348a464731461058f57806349bd5a5e146105af5780635342acb4146105e157600080fd5b8063313ce56714610518578063395093511461053a57806342966c681461055a57600080fd5b806317371a3c1161030d57806318160ddd116102e757806318160ddd1461049957806323b872dd146104b85780632d5a5d34146104d85780632d99d32e146104f857600080fd5b806317371a3c1461043c5780631757354e1461045c57806317ee69951461047b57600080fd5b806301b715311461036057806306fdde0314610391578063095ea7b3146103b35780630b60e564146103e357806313f42605146103fa578063166769d21461041c57600080fd5b3661035b57005b600080fd5b34801561036c57600080fd5b50600a5463ffffffff165b60405163ffffffff90911681526020015b60405180910390f35b34801561039d57600080fd5b506103a6610a9e565b6040516103889190613d07565b3480156103bf57600080fd5b506103d36103ce366004613c2d565b610b30565b6040519015158152602001610388565b3480156103ef57600080fd5b506103f8610b47565b005b34801561040657600080fd5b50600954600160e01b900463ffffffff16610377565b34801561042857600080fd5b506103f8610437366004613cc0565b610c36565b34801561044857600080fd5b506103f8610457366004613c8d565b610d85565b34801561046857600080fd5b506013546301000000900460ff166103d3565b34801561048757600080fd5b5060135462010000900460ff166103d3565b3480156104a557600080fd5b50600b545b604051908152602001610388565b3480156104c457600080fd5b506103d36104d3366004613bb9565b610ec0565b3480156104e457600080fd5b506103f86104f3366004613bfa565b610f96565b34801561050457600080fd5b506103f8610513366004613bfa565b610feb565b34801561052457600080fd5b50600a54600160601b900463ffffffff16610377565b34801561054657600080fd5b506103d3610555366004613c2d565b611098565b34801561056657600080fd5b506103f8610575366004613c59565b6110cf565b34801561058657600080fd5b506103f86110dc565b34801561059b57600080fd5b506103f86105aa366004613c59565b6111ac565b3480156105bb57600080fd5b506008546001600160a01b03165b6040516001600160a01b039091168152602001610388565b3480156105ed57600080fd5b506103d36105fc366004613b46565b6001600160a01b031660009081526003602052604090205460ff1690565b34801561062657600080fd5b506103f8610635366004613b46565b61128c565b34801561064657600080fd5b506103f8610655366004613c72565b611422565b34801561066657600080fd5b506104aa610675366004613b46565b611537565b34801561068657600080fd5b506103f8611596565b34801561069b57600080fd5b506103f86115cc565b3480156106b057600080fd5b506103d36106bf366004613b46565b60146020526000908152604090205460ff1681565b3480156106e057600080fd5b50600c546104aa565b3480156106f557600080fd5b506103f8610704366004613c2d565b61169d565b34801561071557600080fd5b506103f8610724366004613b46565b611725565b34801561073557600080fd5b506103f8610744366004613c8d565b611913565b34801561075557600080fd5b506103d3610764366004613b46565b6001600160a01b031660009081526004602052604090205460ff1690565b34801561078e57600080fd5b506000546001600160a01b03166105c9565b3480156107ac57600080fd5b506103f86107bb366004613b46565b611a5a565b3480156107cc57600080fd5b506103f86107db366004613c8d565b611b0f565b3480156107ec57600080fd5b506103a6611c4a565b34801561080157600080fd5b50600f546104aa565b34801561081657600080fd5b506103f8610825366004613c59565b611c59565b34801561083657600080fd5b50601354610100900460ff166103d3565b34801561085357600080fd5b506103d3610862366004613c2d565b611dbf565b34801561087357600080fd5b506009546105c9906001600160a01b031681565b34801561089357600080fd5b506103d36108a2366004613c2d565b611e50565b3480156108b357600080fd5b506103f86108c2366004613c8d565b611e5d565b3480156108d357600080fd5b50600954600160c01b900463ffffffff16610377565b3480156108f557600080fd5b506103f8610904366004613c8d565b611fb8565b34801561091557600080fd5b5060135461037790600160201b900463ffffffff1681565b34801561093957600080fd5b506103f8610948366004613c2d565b6120fb565b34801561095957600080fd5b50600a54600160201b900463ffffffff16610377565b34801561097b57600080fd5b506103f861098a366004613b46565b6124b8565b34801561099b57600080fd5b506103f86109aa366004613b46565b612536565b3480156109bb57600080fd5b506104aa6109ca366004613b80565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205490565b348015610a0157600080fd5b50600a54600160401b900463ffffffff16610377565b348015610a2357600080fd5b506010546104aa565b348015610a3857600080fd5b506103f8610a47366004613b46565b612619565b348015610a5857600080fd5b50600954600160a01b900463ffffffff16610377565b348015610a7a57600080fd5b506103d3610a89366004613b46565b60156020526000908152604090205460ff1681565b606060118054610aad9061409e565b80601f0160208091040260200160405190810160405280929190818152602001828054610ad99061409e565b8015610b265780601f10610afb57610100808354040283529160200191610b26565b820191906000526020600020905b815481529060010190602001808311610b0957829003601f168201915b5050505050905090565b6000610b3d3384846126b1565b5060015b92915050565b6000546001600160a01b03163314610b7a5760405162461bcd60e51b8152600401610b7190613e2e565b60405180910390fd5b6013546301000000900460ff16610be95760405162461bcd60e51b815260206004820152602d60248201527f4d61726b6574696e6720726577617264206665617475726520697320616c726560448201526c30b23c903234b9b0b13632b21760991b6064820152608401610b71565b610bf4600080611e5d565b610bfe6000611a5a565b6013805463ff000000191690556040517fc006fa0ca84a65d09adbbde41e9930dc143f38f39dfc5fde66f1a18c573243e090600090a1565b6000546001600160a01b03163314610c605760405162461bcd60e51b8152600401610b7190613e2e565b6013546301000000900460ff1615610ccc5760405162461bcd60e51b815260206004820152602960248201527f4d61726b6574696e6720746178206665617475726520697320616c72656164796044820152681032b730b13632b21760b91b6064820152608401610b71565b60008363ffffffff1611610cf25760405162461bcd60e51b8152600401610b7190613d5c565b600a54600160601b900463ffffffff16610d0d836002613eec565b63ffffffff161115610d315760405162461bcd60e51b8152600401610b7190613ddd565b6013805463ff00000019166301000000179055610d4e8383611e5d565b610d5781611a5a565b6040517fdff025d7b2c180bfe5a540637f1772af5b3b0b67452af47016be16ea128a58e190600090a1505050565b6000546001600160a01b03163314610daf5760405162461bcd60e51b8152600401610b7190613e2e565b60135462010000900460ff1615610e135760405162461bcd60e51b815260206004820152602260248201527f526577617264206665617475726520697320616c726561647920656e61626c65604482015261321760f11b6064820152608401610b71565b60008263ffffffff1611610e395760405162461bcd60e51b8152600401610b7190613d5c565b600a54600160601b900463ffffffff16610e54826002613eec565b63ffffffff161115610e785760405162461bcd60e51b8152600401610b7190613ddd565b6013805462ff0000191662010000179055610e938282611fb8565b6040517fba4445e1bffa6a2c7f9686f9082addd1cbaf92d402889b0c26dcc2aa101f658e90600090a15050565b6000610ecd8484846127d5565b6001600160a01b0384166000908152600660209081526040808320338452909152902054821115610f515760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b6064820152608401610b71565b6001600160a01b038416600090815260066020908152604080832033808552925290912054610f8c918691610f87908690614087565b6126b1565b5060019392505050565b6000546001600160a01b03163314610fc05760405162461bcd60e51b8152600401610b7190613e2e565b6001600160a01b03919091166000908152601560205260409020805460ff1916911515919091179055565b6000546001600160a01b031633146110155760405162461bcd60e51b8152600401610b7190613e2e565b6008546001600160a01b038381169116141561108a5760405162461bcd60e51b815260206004820152602e60248201527f546865206d61696e20706169722063616e6e6f742062652072656d6f7665642060448201526d333937b69020a6a6a830b4b9399760911b6064820152608401610b71565b6110948282612c68565b5050565b3360008181526006602090815260408083206001600160a01b03871684529091528120549091610b3d918590610f87908690613ed4565b6110d93382612d07565b50565b6000546001600160a01b031633146111065760405162461bcd60e51b8152600401610b7190613e2e565b60135462010000900460ff1661116a5760405162461bcd60e51b815260206004820152602360248201527f526577617264206665617475726520697320616c72656164792064697361626c60448201526232b21760e91b6064820152608401610b71565b611175600080611fb8565b6013805462ff0000191690556040517f9843194c3ceed34b5019222853f7806a15e8658437ee2a92d9497af23775eb1c90600090a1565b6000546001600160a01b031633146111d65760405162461bcd60e51b8152600401610b7190613e2e565b600c5481106112465760405162461bcd60e51b815260206004820152603660248201527f6d696e546f6b656e734265666f726553776170206d757374206265206c6f776560448201527539103a3430b71031bab93932b73a1039bab838363c9760511b6064820152608401610b71565b601080549082905560408051828152602081018490527fd2f58a5c369e86bc74f3b5be6f9a34224ebb43d603f7acee04b07ef21c7d14bf91015b60405180910390a15050565b6000546001600160a01b031633146112b65760405162461bcd60e51b8152600401610b7190613e2e565b6001600160a01b03811660009081526004602052604090205460ff161561132b5760405162461bcd60e51b8152602060048201526024808201527f4163636f756e7420616c7265616479206578636c756465642066726f6d2072656044820152631dd85c9960e21b6064820152608401610b71565b6001600160a01b03811660009081526001602052604090205415611385576001600160a01b03811660009081526001602052604090205461136b90612fa0565b6001600160a01b0382166000908152600260205260409020555b6001600160a01b0381166000818152600460209081526040808320805460ff191660019081179091556005805491820181559093527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db090920180546001600160a01b0319168417905590519182527fd29a806ac7ba79249e665eb27435d70121361773ea7475dfedd53faf9537782f91015b60405180910390a150565b6000546001600160a01b0316331461144c5760405162461bcd60e51b8152600401610b7190613e2e565b600a5463ffffffff600160401b820481169161147291600160201b820481169116613eec565b61147c9190613eec565b63ffffffff168163ffffffff161015801561149e575060198163ffffffff1611155b6115105760405162461bcd60e51b815260206004820152603e60248201527f5461782072617465206d7573742062652067726561746572207468616e20746f60448201527f74616c206275792074617820616e64206c6f776572207468616e2032352e00006064820152608401610b71565b6013805463ffffffff909216600160201b0267ffffffff0000000019909216919091179055565b6001600160a01b03811660009081526004602052604081205460ff161561157457506001600160a01b031660009081526002602052604090205490565b6001600160a01b038216600090815260016020526040902054610b4190612fa0565b6000546001600160a01b031633146115c05760405162461bcd60e51b8152600401610b7190613e2e565b6115ca6000613024565b565b6000546001600160a01b031633146115f65760405162461bcd60e51b8152600401610b7190613e2e565b601354610100900460ff1661165c5760405162461bcd60e51b815260206004820152602660248201527f4175746f206275726e206665617475726520697320616c72656164792064697360448201526530b13632b21760d11b6064820152608401610b71565b611667600080611913565b6013805461ff00191690556040517f6d4de23ebf419282b51fea4d5ebe9d980cf43df3f9e8ddde137786adfc2c5d6a90600090a1565b60006116a983336109ca565b9050818110156117075760405162461bcd60e51b8152602060048201526024808201527f45524332303a206275726e20616d6f756e74206578636565647320616c6c6f77604482015263616e636560e01b6064820152608401610b71565b6117168333610f878585614087565b6117208383612d07565b505050565b6000546001600160a01b0316331461174f5760405162461bcd60e51b8152600401610b7190613e2e565b6001600160a01b03811660009081526004602052604090205460ff166117b75760405162461bcd60e51b815260206004820152601c60248201527f4163636f756e7420697320616c726561647920696e636c756465642e000000006044820152606401610b71565b60005b6005548110156118d957816001600160a01b0316600582815481106117e1576117e1614136565b6000918252602090912001546001600160a01b031614156118c7576005805461180c90600190614087565b8154811061181c5761181c614136565b600091825260209091200154600580546001600160a01b03909216918390811061184857611848614136565b600091825260208083209190910180546001600160a01b0319166001600160a01b039485161790559184168152600282526040808220829055600490925220805460ff1916905560058054806118a0576118a0614120565b600082815260209020810160001990810180546001600160a01b03191690550190556118d9565b806118d1816140d9565b9150506117ba565b506040516001600160a01b03821681527f3c472973bf47231ac50dbcc7af709a6d6d07cd00bdfa49413339bb89386dbea990602001611417565b6000546001600160a01b0316331461193d5760405162461bcd60e51b8152600401610b7190613e2e565b601354610100900460ff166119c65760405162461bcd60e51b815260206004820152604360248201527f4175746f206275726e2066656174757265206d75737420626520656e61626c6560448201527f642e205472792074686520656e61626c654175746f4275726e2066756e63746960648201526237b71760e91b608482015260a401610b71565b601354600a5463ffffffff600160201b92839004811692600160401b83048216926119f5929190041685613eec565b6119ff9190613eec565b63ffffffff161115611a235760405162461bcd60e51b8152600401610b7190613d91565b600a805463ffffffff93841663ffffffff199091161790556009805491909216600160a01b0263ffffffff60a01b19909116179055565b6000546001600160a01b03163314611a845760405162461bcd60e51b8152600401610b7190613e2e565b600980546001600160a01b038381166001600160a01b0319831681179093556000928352600460205260409092205491169060ff16611ac657611ac68261128c565b611acf826124b8565b604080516001600160a01b038084168252841660208201527fa8efc72ed34f90017df79620d1972d42b8e3b17eb0077fc5fc46cbf1a19ed9a99101611280565b6000546001600160a01b03163314611b395760405162461bcd60e51b8152600401610b7190613e2e565b601354610100900460ff1615611b9f5760405162461bcd60e51b815260206004820152602560248201527f4175746f206275726e206665617475726520697320616c726561647920656e61604482015264313632b21760d91b6064820152608401610b71565b60008263ffffffff1611611bc55760405162461bcd60e51b8152600401610b7190613d5c565b600a54600160601b900463ffffffff16611be0826002613eec565b63ffffffff161115611c045760405162461bcd60e51b8152600401610b7190613ddd565b6013805461ff001916610100179055611c1d8282611913565b6040517f1ae0c73021a2d0e597101e249754f53e8496443b3820ba2128b562a9873ad0b190600090a15050565b606060128054610aad9061409e565b3381611c6482611537565b1015611cc25760405162461bcd60e51b815260206004820152602760248201527f5468652063616c6c6572206d75737420686176652062616c616e6365203e3d2060448201526630b6b7bab73a1760c91b6064820152608401610b71565b6000611cd2836000806000613074565b6001600160a01b03831660009081526004602052604090205490915060ff1615611d265780516001600160a01b03831660009081526002602052604081208054909190611d20908490614087565b90915550505b60a08101516001600160a01b03831660009081526001602052604081208054909190611d53908490614087565b909155505060a0810151600d54611d6a9190614087565b600d8190555082600e6000828254611d829190613ed4565b90915550506040518381527fd0ecdf4854f39daba34ba0e2c1ed0132a7023a5434bffc90b24f3335fb90e5e39060200160405180910390a1505050565b3360009081526006602090815260408083206001600160a01b038616845290915281205482811015611e415760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610b71565b610f8c3385610f878685614087565b6000610b3d3384846127d5565b6000546001600160a01b03163314611e875760405162461bcd60e51b8152600401610b7190613e2e565b6013546301000000900460ff16611f1d5760405162461bcd60e51b815260206004820152604e60248201527f4d61726b6574696e67207265776172642066656174757265206d75737420626560448201527f20656e61626c65642e205472792074686520656e61626c654d61726b6574696e60648201526d33aa30bc10333ab731ba34b7b71760911b608482015260a401610b71565b601354600a5463ffffffff600160201b928390048116928592611f469291810482169116613eec565b611f509190613eec565b63ffffffff161115611f745760405162461bcd60e51b8152600401610b7190613d91565b600a805463ffffffff938416600160401b026bffffffff0000000000000000199091161790556009805491909216600160e01b026001600160e01b03909116179055565b6000546001600160a01b03163314611fe25760405162461bcd60e51b8152600401610b7190613e2e565b60135462010000900460ff166120605760405162461bcd60e51b815260206004820152603e60248201527f5265776172642066656174757265206d75737420626520656e61626c65642e2060448201527f5472792074686520656e61626c655265776172642066756e6374696f6e2e00006064820152608401610b71565b601354600a5463ffffffff600160201b909204821691600160401b820481169161208c91869116613eec565b6120969190613eec565b63ffffffff1611156120ba5760405162461bcd60e51b8152600401610b7190613d91565b600a805463ffffffff938416600160201b0267ffffffff00000000199091161790556009805491909216600160c01b0263ffffffff60c01b19909116179055565b6000546001600160a01b031633146121255760405162461bcd60e51b8152600401610b7190613e2e565b6000829050806001600160a01b031663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b15801561216357600080fd5b505afa158015612177573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061219b9190613b63565b6001600160a01b031663e6a4390530836001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b1580156121e357600080fd5b505afa1580156121f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221b9190613b63565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260440160206040518083038186803b15801561226157600080fd5b505afa158015612275573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122999190613b63565b600880546001600160a01b0319166001600160a01b0392909216918217905561244e57806001600160a01b031663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b1580156122f557600080fd5b505afa158015612309573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232d9190613b63565b6001600160a01b031663c9c6539630836001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b15801561237557600080fd5b505afa158015612389573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ad9190613b63565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381600087803b1580156123f557600080fd5b505af1158015612409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242d9190613b63565b600880546001600160a01b0319166001600160a01b03929092169190911790555b600780546001600160a01b0319166001600160a01b038381169190911790915560085461247d91166001612c68565b6001600160a01b03811660009081526004602052604090205460ff166124a6576124a68161128c565b6124af816124b8565b611720826111ac565b6000546001600160a01b031633146124e25760405162461bcd60e51b8152600401610b7190613e2e565b6001600160a01b038116600081815260036020908152604091829020805460ff1916600117905590519182527f7e35d6b74d35c333860340884eeca4e63b18cb9d73ce17a147a1952654365b5e9101611417565b6000546001600160a01b031633146125605760405162461bcd60e51b8152600401610b7190613e2e565b6001600160a01b03811660009081526003602052604090205460ff166125c85760405162461bcd60e51b815260206004820152601c60248201527f4163636f756e7420697320616c726561647920696e636c756465642e000000006044820152606401610b71565b6001600160a01b038116600081815260036020908152604091829020805460ff1916905590519182527fc782889d4eb26c6effaa6305a7075c22c2a6e2919ddf49a4a851fecf59cfc75f9101611417565b6000546001600160a01b031633146126435760405162461bcd60e51b8152600401610b7190613e2e565b6001600160a01b0381166126a85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b71565b6110d981613024565b6001600160a01b0383166127135760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610b71565b6001600160a01b0382166127745760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610b71565b6001600160a01b0383811660008181526006602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166128395760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610b71565b6001600160a01b03821661289b5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610b71565b806128a584611537565b10156129025760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610b71565b6001600160a01b03831660009081526015602052604090205460ff1615801561294457506001600160a01b03821660009081526015602052604090205460ff16155b6129865760405162461bcd60e51b8152602060048201526013602482015272426c61636b6c6973746564206164647265737360681b6044820152606401610b71565b6000546001600160a01b038481169116148015906129b257506000546001600160a01b03838116911614155b156129c0576129c0836130a6565b6001600160a01b03831660009081526014602052604081205460ff16156129e5575060015b6001600160a01b03831660009081526014602052604081205460ff1615612a0a575060015b6001600160a01b038516600090815260036020526040812054612a6190859060ff161580612a595750848015612a5957506001600160a01b03871660009081526003602052604090205460ff16155b158486613074565b6001600160a01b03871660009081526004602052604090205490915060ff168015612aa557506001600160a01b03851660009081526004602052604090205460ff16155b15612aba57612ab586868361311f565b612bb8565b6001600160a01b03861660009081526004602052604090205460ff16158015612afb57506001600160a01b03851660009081526004602052604090205460ff165b15612b0b57612ab58686836131d4565b6001600160a01b03861660009081526004602052604090205460ff16158015612b4d57506001600160a01b03851660009081526004602052604090205460ff16155b15612b5d57612ab5868683613271565b6001600160a01b03861660009081526004602052604090205460ff168015612b9d57506001600160a01b03851660009081526004602052604090205460ff165b15612bad57612ab5868683613299565b612bb8868683613271565b846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360800151604051612c0191815260200190565b60405180910390a36001600160a01b03861660009081526003602052604090205460ff161580612c525750828015612c5257506001600160a01b03851660009081526003602052604090205460ff16155b15612c6057612c60816132f5565b505050505050565b6001600160a01b0382166000908152601460205260409020805460ff19168215801591909117909155612cc7576001600160a01b03821660009081526004602052604090205460ff16612cbe57612cbe8261128c565b612cc7826124b8565b604080516001600160a01b038416815282151560208201527f9a05f836a81b64d2d3ee62b752e87947ab26a9fdcd5b2572b1744ae8499b3aac9101611280565b6001600160a01b03821661dead1415612d6c5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865206275726e206164647265736044820152607360f81b6064820152608401610b71565b6000612d7783611537565b905081811015612dd45760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610b71565b6000612ddf83613400565b6001600160a01b03851660009081526004602052604090205490915060ff1615612e31576001600160a01b03841660009081526002602052604081208054859290612e2b908490614087565b90915550505b6001600160a01b03841660009081526001602052604081208054839290612e59908490614087565b909155505061dead600090815260026020527f6a9609baa168169acaea398c4407efea4be641bb08e21e88806d9836fd9333cc8054859290612e9c908490613ed4565b909155505061dead600090815260016020527fb34209a263f6c38fe55f099e9e70f9d67e93982480ff3234a5e0108028ad164d8054839290612edf908490613ed4565b9250508190555082600c6000828254612ef89190614087565b9250508190555082600f6000828254612f119190613ed4565b9091555050604080516001600160a01b0386168152602081018590527fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5910160405180910390a160405183815261dead906001600160a01b038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a350505050565b6000600d548211156130075760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e74206d757374206265206c657373207468616e20746f74616c207260448201526965666c656374696f6e7360b01b6064820152608401610b71565b6000613011613417565b905061301d8184613f14565b9392505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61307c613ada565b613084613ada565b8581526130938186868661343a565b61309d8186613655565b95945050505050565b6013546301000000900460ff16156110d95730600090815260026020526040902054601054811080159081906130df575060135460ff16155b801561310457506001600160a01b03831660009081526014602052604090205460ff16155b1561172057600954611720906001600160a01b03168361371a565b80516001600160a01b0384166000908152600260205260409020546131449190614087565b6001600160a01b03841660009081526002602090815260408083209390935560a084015160019091529190205461317b9190614087565b6001600160a01b0380851660009081526001602052604080822093909355610120840151918516815291909120546131b39190613ed4565b6001600160a01b039092166000908152600160205260409020919091555050565b60a08101516001600160a01b0384166000908152600160205260409020546131fc9190614087565b6001600160a01b03808516600090815260016020908152604080832094909455608085015192861682526002905291909120546132399190613ed4565b6001600160a01b0383166000908152600260209081526040808320939093556101208401516001909152919020546131b39190613ed4565b60a08101516001600160a01b03841660009081526001602052604090205461317b9190614087565b80516001600160a01b0384166000908152600260205260409020546132be9190614087565b6001600160a01b03841660009081526002602090815260408083209390935560a08401516001909152919020546131fc9190614087565b601354610100900460ff16156133775760208082015130600090815260029092526040822080549192909161332b908490613ed4565b909155505060c08101513060009081526001602052604081208054909190613354908490613ed4565b909155506133699050303383602001516126b1565b61337730826020015161169d565b6013546301000000900460ff16156133dd57606081015130600090815260026020526040812080549091906133ad908490613ed4565b909155505061010081015130600090815260016020526040812080549091906133d7908490613ed4565b90915550505b60135462010000900460ff16156110d9576110d98160e001518260400151613724565b60008061340b613417565b905061301d818461403c565b6000806000613424613753565b90925090506134338183613f14565b9250505090565b821561344c578351608085015261364f565b80156134dd578351600a54600954613475929163ffffffff90811691600160a01b9004166138d6565b60208501528351600a546009546134a4929163ffffffff600160401b909104811691600160e01b9004166138d6565b60608501528351600a546009546134d3929163ffffffff600160201b909104811691600160c01b9004166138d6565b604085015261361a565b811561361a57600a5460009063ffffffff600160201b820481169161350c91600160401b820481169116613eec565b6135169190613eec565b905063ffffffff811615613618578451601354600a5461356c9291849161354d9163ffffffff600160201b9091048116911661405b565b6135579190613f28565b600954600160a01b900463ffffffff166138d6565b60208601528451601354600a546135c0929184916135a19163ffffffff600160201b909104811691600160401b90041661405b565b6135ab9190613f28565b600954600160e01b900463ffffffff166138d6565b60608601528451601354600a54613612929184916135f39163ffffffff600160201b91829004811692919091041661405b565b6135fd9190613f28565b600954600160c01b900463ffffffff166138d6565b60408601525b505b60608401516040850151602086015186516136359190614087565b61363f9190614087565b6136499190614087565b60808501525b50505050565b600061365f613417565b835190915061366f90829061403c565b60a0840152811561368a5760a0830151610120840152505050565b825161369790829061403c565b60a084015260208301516136ac90829061403c565b60c084015260608301516136c190829061403c565b61010084015260408301516136d790829061403c565b60e0840181905261010084015160c085015160a08601519192916136fb9190614087565b6137059190614087565b61370f9190614087565b610120840152505050565b6110948282613911565b81600d546137329190614087565b600d8190555080600e600082825461374a9190613ed4565b90915550505050565b600d54600b546000918291825b6005548110156138a55782600160006005848154811061378257613782614136565b60009182526020808320909101546001600160a01b0316835282019290925260400190205411806137ed57508160026000600584815481106137c6576137c6614136565b60009182526020808320909101546001600160a01b03168352820192909252604001902054115b1561380357600d54600b54945094505050509091565b600160006005838154811061381a5761381a614136565b60009182526020808320909101546001600160a01b031683528201929092526040019020546138499084614087565b9250600260006005838154811061386257613862614136565b60009182526020808320909101546001600160a01b031683528201929092526040019020546138919083614087565b91508061389d816140d9565b915050613760565b50600b54600d546138b69190613f14565b8210156138cd57600d54600b549350935050509091565b90939092509050565b600060646138e583600a613f8e565b6138f563ffffffff86168761403c565b6138ff9190613f14565b6139099190613f14565b949350505050565b60135460ff16156139595760405162461bcd60e51b815260206004820152601260248201527121bab93932b73a363c9034b71039bbb0b81760711b6044820152606401610b71565b6013805460ff19166001179055604080516002808252606082018352600092602083019080368337019050509050308160008151811061399b5761399b614136565b6001600160a01b03928316602091820292909201810191909152600754604080516315ab88c960e31b81529051919093169263ad5c4648926004808301939192829003018186803b1580156139ef57600080fd5b505afa158015613a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a279190613b63565b81600181518110613a3a57613a3a614136565b6001600160a01b039283166020918202929092010152600754613a6091309116846126b1565b60075460405163791ac94760e01b81526001600160a01b039091169063791ac94790613a99908590600090869089904290600401613e63565b600060405180830381600087803b158015613ab357600080fd5b505af1158015613ac7573d6000803e3d6000fd5b50506013805460ff191690555050505050565b604051806101400160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b803563ffffffff81168114613b4157600080fd5b919050565b600060208284031215613b5857600080fd5b813561301d8161414c565b600060208284031215613b7557600080fd5b815161301d8161414c565b60008060408385031215613b9357600080fd5b8235613b9e8161414c565b91506020830135613bae8161414c565b809150509250929050565b600080600060608486031215613bce57600080fd5b8335613bd98161414c565b92506020840135613be98161414c565b929592945050506040919091013590565b60008060408385031215613c0d57600080fd5b8235613c188161414c565b915060208301358015158114613bae57600080fd5b60008060408385031215613c4057600080fd5b8235613c4b8161414c565b946020939093013593505050565b600060208284031215613c6b57600080fd5b5035919050565b600060208284031215613c8457600080fd5b61301d82613b2d565b60008060408385031215613ca057600080fd5b613ca983613b2d565b9150613cb760208401613b2d565b90509250929050565b600080600060608486031215613cd557600080fd5b613cde84613b2d565b9250613cec60208501613b2d565b91506040840135613cfc8161414c565b809150509250925092565b600060208083528351808285015260005b81811015613d3457858101830151858201604001528201613d18565b81811115613d46576000604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f5461782072617465206d7573742062652067726561746572207468616e20302e604082015260600190565b6020808252602c908201527f546f74616c20746178206d757374206265206c6f776572207468616e2073656c60408201526b6c546178496e63726561736560a01b606082015260800190565b60208082526031908201527f54617820646563696d616c73206d757374206265206c657373207468616e207460408201527037b5b2b7103232b1b4b6b0b6399016901960791b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b81811015613eb35784516001600160a01b031683529383019391830191600101613e8e565b50506001600160a01b03969096166060850152505050608001529392505050565b60008219821115613ee757613ee76140f4565b500190565b600063ffffffff808316818516808303821115613f0b57613f0b6140f4565b01949350505050565b600082613f2357613f2361410a565b500490565b600063ffffffff80841680613f3f57613f3f61410a565b92169190910492915050565b600181815b80851115613f86578160001904821115613f6c57613f6c6140f4565b80851615613f7957918102915b93841c9390800290613f50565b509250929050565b600061301d63ffffffff841683600082613faa57506001610b41565b81613fb757506000610b41565b8160018114613fcd5760028114613fd757613ff3565b6001915050610b41565b60ff841115613fe857613fe86140f4565b50506001821b610b41565b5060208310610133831016604e8410600b8410161715614016575081810a610b41565b6140208383613f4b565b8060001904821115614034576140346140f4565b029392505050565b6000816000190483118215151615614056576140566140f4565b500290565b600063ffffffff8083168185168183048111821515161561407e5761407e6140f4565b02949350505050565b600082821015614099576140996140f4565b500390565b600181811c908216806140b257607f821691505b602082108114156140d357634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156140ed576140ed6140f4565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03811681146110d957600080fdfea264697066735822122090be67728d55074792bccfb54af13090a31ebe493008497f6038eb9a86b756cf64736f6c6343000807003354617820646563696d616c73206d757374206265206c657373207468616e20745461782072617465206d7573742062652067726561746572207468616e20302e546f74616c20746178206d757374206265206c6f776572207468616e2073656c4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572

Deployed Bytecode

0x6080604052600436106103545760003560e01c806379cc6790116101c6578063aa5e8752116100f7578063daa9334111610095578063e5d41c6b1161006f578063e5d41c6b14610a17578063f2fde38b14610a2c578063fbfa089c14610a4c578063fe575a8714610a6e57600080fd5b8063daa933411461098f578063dd62ed3e146109af578063e2314bea146109f557600080fd5b8063becc01e4116100d1578063becc01e414610909578063c08a95f11461092d578063d42ac3771461094d578063d6b4212b1461096f57600080fd5b8063aa5e8752146108a7578063ad8e91dd146108c7578063af1d8554146108e957600080fd5b806395d89b41116101645780639dd255da1161013e5780639dd255da1461082a578063a457c2d714610847578063a5ece94114610867578063a9059cbb1461088757600080fd5b806395d89b41146107e0578063966ff650146107f557806397dc4a131461080a57600080fd5b806388f82020116101a057806388f82020146107495780638da5cb5b14610782578063906e9dd0146107a057806390c364b2146107c057600080fd5b806379cc6790146106e95780638397295114610709578063882f86d61461072957600080fd5b8063313ce567116102a05780636049876e1161023e578063715018a611610218578063715018a61461067a5780637656e1461461068f57806376856557146106a4578063771282f6146106d457600080fd5b80636049876e1461061a57806368349f491461063a57806370a082311461065a57600080fd5b8063470d5cbd1161027a578063470d5cbd1461057a57806348a464731461058f57806349bd5a5e146105af5780635342acb4146105e157600080fd5b8063313ce56714610518578063395093511461053a57806342966c681461055a57600080fd5b806317371a3c1161030d57806318160ddd116102e757806318160ddd1461049957806323b872dd146104b85780632d5a5d34146104d85780632d99d32e146104f857600080fd5b806317371a3c1461043c5780631757354e1461045c57806317ee69951461047b57600080fd5b806301b715311461036057806306fdde0314610391578063095ea7b3146103b35780630b60e564146103e357806313f42605146103fa578063166769d21461041c57600080fd5b3661035b57005b600080fd5b34801561036c57600080fd5b50600a5463ffffffff165b60405163ffffffff90911681526020015b60405180910390f35b34801561039d57600080fd5b506103a6610a9e565b6040516103889190613d07565b3480156103bf57600080fd5b506103d36103ce366004613c2d565b610b30565b6040519015158152602001610388565b3480156103ef57600080fd5b506103f8610b47565b005b34801561040657600080fd5b50600954600160e01b900463ffffffff16610377565b34801561042857600080fd5b506103f8610437366004613cc0565b610c36565b34801561044857600080fd5b506103f8610457366004613c8d565b610d85565b34801561046857600080fd5b506013546301000000900460ff166103d3565b34801561048757600080fd5b5060135462010000900460ff166103d3565b3480156104a557600080fd5b50600b545b604051908152602001610388565b3480156104c457600080fd5b506103d36104d3366004613bb9565b610ec0565b3480156104e457600080fd5b506103f86104f3366004613bfa565b610f96565b34801561050457600080fd5b506103f8610513366004613bfa565b610feb565b34801561052457600080fd5b50600a54600160601b900463ffffffff16610377565b34801561054657600080fd5b506103d3610555366004613c2d565b611098565b34801561056657600080fd5b506103f8610575366004613c59565b6110cf565b34801561058657600080fd5b506103f86110dc565b34801561059b57600080fd5b506103f86105aa366004613c59565b6111ac565b3480156105bb57600080fd5b506008546001600160a01b03165b6040516001600160a01b039091168152602001610388565b3480156105ed57600080fd5b506103d36105fc366004613b46565b6001600160a01b031660009081526003602052604090205460ff1690565b34801561062657600080fd5b506103f8610635366004613b46565b61128c565b34801561064657600080fd5b506103f8610655366004613c72565b611422565b34801561066657600080fd5b506104aa610675366004613b46565b611537565b34801561068657600080fd5b506103f8611596565b34801561069b57600080fd5b506103f86115cc565b3480156106b057600080fd5b506103d36106bf366004613b46565b60146020526000908152604090205460ff1681565b3480156106e057600080fd5b50600c546104aa565b3480156106f557600080fd5b506103f8610704366004613c2d565b61169d565b34801561071557600080fd5b506103f8610724366004613b46565b611725565b34801561073557600080fd5b506103f8610744366004613c8d565b611913565b34801561075557600080fd5b506103d3610764366004613b46565b6001600160a01b031660009081526004602052604090205460ff1690565b34801561078e57600080fd5b506000546001600160a01b03166105c9565b3480156107ac57600080fd5b506103f86107bb366004613b46565b611a5a565b3480156107cc57600080fd5b506103f86107db366004613c8d565b611b0f565b3480156107ec57600080fd5b506103a6611c4a565b34801561080157600080fd5b50600f546104aa565b34801561081657600080fd5b506103f8610825366004613c59565b611c59565b34801561083657600080fd5b50601354610100900460ff166103d3565b34801561085357600080fd5b506103d3610862366004613c2d565b611dbf565b34801561087357600080fd5b506009546105c9906001600160a01b031681565b34801561089357600080fd5b506103d36108a2366004613c2d565b611e50565b3480156108b357600080fd5b506103f86108c2366004613c8d565b611e5d565b3480156108d357600080fd5b50600954600160c01b900463ffffffff16610377565b3480156108f557600080fd5b506103f8610904366004613c8d565b611fb8565b34801561091557600080fd5b5060135461037790600160201b900463ffffffff1681565b34801561093957600080fd5b506103f8610948366004613c2d565b6120fb565b34801561095957600080fd5b50600a54600160201b900463ffffffff16610377565b34801561097b57600080fd5b506103f861098a366004613b46565b6124b8565b34801561099b57600080fd5b506103f86109aa366004613b46565b612536565b3480156109bb57600080fd5b506104aa6109ca366004613b80565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205490565b348015610a0157600080fd5b50600a54600160401b900463ffffffff16610377565b348015610a2357600080fd5b506010546104aa565b348015610a3857600080fd5b506103f8610a47366004613b46565b612619565b348015610a5857600080fd5b50600954600160a01b900463ffffffff16610377565b348015610a7a57600080fd5b506103d3610a89366004613b46565b60156020526000908152604090205460ff1681565b606060118054610aad9061409e565b80601f0160208091040260200160405190810160405280929190818152602001828054610ad99061409e565b8015610b265780601f10610afb57610100808354040283529160200191610b26565b820191906000526020600020905b815481529060010190602001808311610b0957829003601f168201915b5050505050905090565b6000610b3d3384846126b1565b5060015b92915050565b6000546001600160a01b03163314610b7a5760405162461bcd60e51b8152600401610b7190613e2e565b60405180910390fd5b6013546301000000900460ff16610be95760405162461bcd60e51b815260206004820152602d60248201527f4d61726b6574696e6720726577617264206665617475726520697320616c726560448201526c30b23c903234b9b0b13632b21760991b6064820152608401610b71565b610bf4600080611e5d565b610bfe6000611a5a565b6013805463ff000000191690556040517fc006fa0ca84a65d09adbbde41e9930dc143f38f39dfc5fde66f1a18c573243e090600090a1565b6000546001600160a01b03163314610c605760405162461bcd60e51b8152600401610b7190613e2e565b6013546301000000900460ff1615610ccc5760405162461bcd60e51b815260206004820152602960248201527f4d61726b6574696e6720746178206665617475726520697320616c72656164796044820152681032b730b13632b21760b91b6064820152608401610b71565b60008363ffffffff1611610cf25760405162461bcd60e51b8152600401610b7190613d5c565b600a54600160601b900463ffffffff16610d0d836002613eec565b63ffffffff161115610d315760405162461bcd60e51b8152600401610b7190613ddd565b6013805463ff00000019166301000000179055610d4e8383611e5d565b610d5781611a5a565b6040517fdff025d7b2c180bfe5a540637f1772af5b3b0b67452af47016be16ea128a58e190600090a1505050565b6000546001600160a01b03163314610daf5760405162461bcd60e51b8152600401610b7190613e2e565b60135462010000900460ff1615610e135760405162461bcd60e51b815260206004820152602260248201527f526577617264206665617475726520697320616c726561647920656e61626c65604482015261321760f11b6064820152608401610b71565b60008263ffffffff1611610e395760405162461bcd60e51b8152600401610b7190613d5c565b600a54600160601b900463ffffffff16610e54826002613eec565b63ffffffff161115610e785760405162461bcd60e51b8152600401610b7190613ddd565b6013805462ff0000191662010000179055610e938282611fb8565b6040517fba4445e1bffa6a2c7f9686f9082addd1cbaf92d402889b0c26dcc2aa101f658e90600090a15050565b6000610ecd8484846127d5565b6001600160a01b0384166000908152600660209081526040808320338452909152902054821115610f515760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b6064820152608401610b71565b6001600160a01b038416600090815260066020908152604080832033808552925290912054610f8c918691610f87908690614087565b6126b1565b5060019392505050565b6000546001600160a01b03163314610fc05760405162461bcd60e51b8152600401610b7190613e2e565b6001600160a01b03919091166000908152601560205260409020805460ff1916911515919091179055565b6000546001600160a01b031633146110155760405162461bcd60e51b8152600401610b7190613e2e565b6008546001600160a01b038381169116141561108a5760405162461bcd60e51b815260206004820152602e60248201527f546865206d61696e20706169722063616e6e6f742062652072656d6f7665642060448201526d333937b69020a6a6a830b4b9399760911b6064820152608401610b71565b6110948282612c68565b5050565b3360008181526006602090815260408083206001600160a01b03871684529091528120549091610b3d918590610f87908690613ed4565b6110d93382612d07565b50565b6000546001600160a01b031633146111065760405162461bcd60e51b8152600401610b7190613e2e565b60135462010000900460ff1661116a5760405162461bcd60e51b815260206004820152602360248201527f526577617264206665617475726520697320616c72656164792064697361626c60448201526232b21760e91b6064820152608401610b71565b611175600080611fb8565b6013805462ff0000191690556040517f9843194c3ceed34b5019222853f7806a15e8658437ee2a92d9497af23775eb1c90600090a1565b6000546001600160a01b031633146111d65760405162461bcd60e51b8152600401610b7190613e2e565b600c5481106112465760405162461bcd60e51b815260206004820152603660248201527f6d696e546f6b656e734265666f726553776170206d757374206265206c6f776560448201527539103a3430b71031bab93932b73a1039bab838363c9760511b6064820152608401610b71565b601080549082905560408051828152602081018490527fd2f58a5c369e86bc74f3b5be6f9a34224ebb43d603f7acee04b07ef21c7d14bf91015b60405180910390a15050565b6000546001600160a01b031633146112b65760405162461bcd60e51b8152600401610b7190613e2e565b6001600160a01b03811660009081526004602052604090205460ff161561132b5760405162461bcd60e51b8152602060048201526024808201527f4163636f756e7420616c7265616479206578636c756465642066726f6d2072656044820152631dd85c9960e21b6064820152608401610b71565b6001600160a01b03811660009081526001602052604090205415611385576001600160a01b03811660009081526001602052604090205461136b90612fa0565b6001600160a01b0382166000908152600260205260409020555b6001600160a01b0381166000818152600460209081526040808320805460ff191660019081179091556005805491820181559093527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db090920180546001600160a01b0319168417905590519182527fd29a806ac7ba79249e665eb27435d70121361773ea7475dfedd53faf9537782f91015b60405180910390a150565b6000546001600160a01b0316331461144c5760405162461bcd60e51b8152600401610b7190613e2e565b600a5463ffffffff600160401b820481169161147291600160201b820481169116613eec565b61147c9190613eec565b63ffffffff168163ffffffff161015801561149e575060198163ffffffff1611155b6115105760405162461bcd60e51b815260206004820152603e60248201527f5461782072617465206d7573742062652067726561746572207468616e20746f60448201527f74616c206275792074617820616e64206c6f776572207468616e2032352e00006064820152608401610b71565b6013805463ffffffff909216600160201b0267ffffffff0000000019909216919091179055565b6001600160a01b03811660009081526004602052604081205460ff161561157457506001600160a01b031660009081526002602052604090205490565b6001600160a01b038216600090815260016020526040902054610b4190612fa0565b6000546001600160a01b031633146115c05760405162461bcd60e51b8152600401610b7190613e2e565b6115ca6000613024565b565b6000546001600160a01b031633146115f65760405162461bcd60e51b8152600401610b7190613e2e565b601354610100900460ff1661165c5760405162461bcd60e51b815260206004820152602660248201527f4175746f206275726e206665617475726520697320616c72656164792064697360448201526530b13632b21760d11b6064820152608401610b71565b611667600080611913565b6013805461ff00191690556040517f6d4de23ebf419282b51fea4d5ebe9d980cf43df3f9e8ddde137786adfc2c5d6a90600090a1565b60006116a983336109ca565b9050818110156117075760405162461bcd60e51b8152602060048201526024808201527f45524332303a206275726e20616d6f756e74206578636565647320616c6c6f77604482015263616e636560e01b6064820152608401610b71565b6117168333610f878585614087565b6117208383612d07565b505050565b6000546001600160a01b0316331461174f5760405162461bcd60e51b8152600401610b7190613e2e565b6001600160a01b03811660009081526004602052604090205460ff166117b75760405162461bcd60e51b815260206004820152601c60248201527f4163636f756e7420697320616c726561647920696e636c756465642e000000006044820152606401610b71565b60005b6005548110156118d957816001600160a01b0316600582815481106117e1576117e1614136565b6000918252602090912001546001600160a01b031614156118c7576005805461180c90600190614087565b8154811061181c5761181c614136565b600091825260209091200154600580546001600160a01b03909216918390811061184857611848614136565b600091825260208083209190910180546001600160a01b0319166001600160a01b039485161790559184168152600282526040808220829055600490925220805460ff1916905560058054806118a0576118a0614120565b600082815260209020810160001990810180546001600160a01b03191690550190556118d9565b806118d1816140d9565b9150506117ba565b506040516001600160a01b03821681527f3c472973bf47231ac50dbcc7af709a6d6d07cd00bdfa49413339bb89386dbea990602001611417565b6000546001600160a01b0316331461193d5760405162461bcd60e51b8152600401610b7190613e2e565b601354610100900460ff166119c65760405162461bcd60e51b815260206004820152604360248201527f4175746f206275726e2066656174757265206d75737420626520656e61626c6560448201527f642e205472792074686520656e61626c654175746f4275726e2066756e63746960648201526237b71760e91b608482015260a401610b71565b601354600a5463ffffffff600160201b92839004811692600160401b83048216926119f5929190041685613eec565b6119ff9190613eec565b63ffffffff161115611a235760405162461bcd60e51b8152600401610b7190613d91565b600a805463ffffffff93841663ffffffff199091161790556009805491909216600160a01b0263ffffffff60a01b19909116179055565b6000546001600160a01b03163314611a845760405162461bcd60e51b8152600401610b7190613e2e565b600980546001600160a01b038381166001600160a01b0319831681179093556000928352600460205260409092205491169060ff16611ac657611ac68261128c565b611acf826124b8565b604080516001600160a01b038084168252841660208201527fa8efc72ed34f90017df79620d1972d42b8e3b17eb0077fc5fc46cbf1a19ed9a99101611280565b6000546001600160a01b03163314611b395760405162461bcd60e51b8152600401610b7190613e2e565b601354610100900460ff1615611b9f5760405162461bcd60e51b815260206004820152602560248201527f4175746f206275726e206665617475726520697320616c726561647920656e61604482015264313632b21760d91b6064820152608401610b71565b60008263ffffffff1611611bc55760405162461bcd60e51b8152600401610b7190613d5c565b600a54600160601b900463ffffffff16611be0826002613eec565b63ffffffff161115611c045760405162461bcd60e51b8152600401610b7190613ddd565b6013805461ff001916610100179055611c1d8282611913565b6040517f1ae0c73021a2d0e597101e249754f53e8496443b3820ba2128b562a9873ad0b190600090a15050565b606060128054610aad9061409e565b3381611c6482611537565b1015611cc25760405162461bcd60e51b815260206004820152602760248201527f5468652063616c6c6572206d75737420686176652062616c616e6365203e3d2060448201526630b6b7bab73a1760c91b6064820152608401610b71565b6000611cd2836000806000613074565b6001600160a01b03831660009081526004602052604090205490915060ff1615611d265780516001600160a01b03831660009081526002602052604081208054909190611d20908490614087565b90915550505b60a08101516001600160a01b03831660009081526001602052604081208054909190611d53908490614087565b909155505060a0810151600d54611d6a9190614087565b600d8190555082600e6000828254611d829190613ed4565b90915550506040518381527fd0ecdf4854f39daba34ba0e2c1ed0132a7023a5434bffc90b24f3335fb90e5e39060200160405180910390a1505050565b3360009081526006602090815260408083206001600160a01b038616845290915281205482811015611e415760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610b71565b610f8c3385610f878685614087565b6000610b3d3384846127d5565b6000546001600160a01b03163314611e875760405162461bcd60e51b8152600401610b7190613e2e565b6013546301000000900460ff16611f1d5760405162461bcd60e51b815260206004820152604e60248201527f4d61726b6574696e67207265776172642066656174757265206d75737420626560448201527f20656e61626c65642e205472792074686520656e61626c654d61726b6574696e60648201526d33aa30bc10333ab731ba34b7b71760911b608482015260a401610b71565b601354600a5463ffffffff600160201b928390048116928592611f469291810482169116613eec565b611f509190613eec565b63ffffffff161115611f745760405162461bcd60e51b8152600401610b7190613d91565b600a805463ffffffff938416600160401b026bffffffff0000000000000000199091161790556009805491909216600160e01b026001600160e01b03909116179055565b6000546001600160a01b03163314611fe25760405162461bcd60e51b8152600401610b7190613e2e565b60135462010000900460ff166120605760405162461bcd60e51b815260206004820152603e60248201527f5265776172642066656174757265206d75737420626520656e61626c65642e2060448201527f5472792074686520656e61626c655265776172642066756e6374696f6e2e00006064820152608401610b71565b601354600a5463ffffffff600160201b909204821691600160401b820481169161208c91869116613eec565b6120969190613eec565b63ffffffff1611156120ba5760405162461bcd60e51b8152600401610b7190613d91565b600a805463ffffffff938416600160201b0267ffffffff00000000199091161790556009805491909216600160c01b0263ffffffff60c01b19909116179055565b6000546001600160a01b031633146121255760405162461bcd60e51b8152600401610b7190613e2e565b6000829050806001600160a01b031663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b15801561216357600080fd5b505afa158015612177573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061219b9190613b63565b6001600160a01b031663e6a4390530836001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b1580156121e357600080fd5b505afa1580156121f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221b9190613b63565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260440160206040518083038186803b15801561226157600080fd5b505afa158015612275573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122999190613b63565b600880546001600160a01b0319166001600160a01b0392909216918217905561244e57806001600160a01b031663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b1580156122f557600080fd5b505afa158015612309573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232d9190613b63565b6001600160a01b031663c9c6539630836001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b15801561237557600080fd5b505afa158015612389573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ad9190613b63565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381600087803b1580156123f557600080fd5b505af1158015612409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242d9190613b63565b600880546001600160a01b0319166001600160a01b03929092169190911790555b600780546001600160a01b0319166001600160a01b038381169190911790915560085461247d91166001612c68565b6001600160a01b03811660009081526004602052604090205460ff166124a6576124a68161128c565b6124af816124b8565b611720826111ac565b6000546001600160a01b031633146124e25760405162461bcd60e51b8152600401610b7190613e2e565b6001600160a01b038116600081815260036020908152604091829020805460ff1916600117905590519182527f7e35d6b74d35c333860340884eeca4e63b18cb9d73ce17a147a1952654365b5e9101611417565b6000546001600160a01b031633146125605760405162461bcd60e51b8152600401610b7190613e2e565b6001600160a01b03811660009081526003602052604090205460ff166125c85760405162461bcd60e51b815260206004820152601c60248201527f4163636f756e7420697320616c726561647920696e636c756465642e000000006044820152606401610b71565b6001600160a01b038116600081815260036020908152604091829020805460ff1916905590519182527fc782889d4eb26c6effaa6305a7075c22c2a6e2919ddf49a4a851fecf59cfc75f9101611417565b6000546001600160a01b031633146126435760405162461bcd60e51b8152600401610b7190613e2e565b6001600160a01b0381166126a85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b71565b6110d981613024565b6001600160a01b0383166127135760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610b71565b6001600160a01b0382166127745760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610b71565b6001600160a01b0383811660008181526006602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166128395760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610b71565b6001600160a01b03821661289b5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610b71565b806128a584611537565b10156129025760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610b71565b6001600160a01b03831660009081526015602052604090205460ff1615801561294457506001600160a01b03821660009081526015602052604090205460ff16155b6129865760405162461bcd60e51b8152602060048201526013602482015272426c61636b6c6973746564206164647265737360681b6044820152606401610b71565b6000546001600160a01b038481169116148015906129b257506000546001600160a01b03838116911614155b156129c0576129c0836130a6565b6001600160a01b03831660009081526014602052604081205460ff16156129e5575060015b6001600160a01b03831660009081526014602052604081205460ff1615612a0a575060015b6001600160a01b038516600090815260036020526040812054612a6190859060ff161580612a595750848015612a5957506001600160a01b03871660009081526003602052604090205460ff16155b158486613074565b6001600160a01b03871660009081526004602052604090205490915060ff168015612aa557506001600160a01b03851660009081526004602052604090205460ff16155b15612aba57612ab586868361311f565b612bb8565b6001600160a01b03861660009081526004602052604090205460ff16158015612afb57506001600160a01b03851660009081526004602052604090205460ff165b15612b0b57612ab58686836131d4565b6001600160a01b03861660009081526004602052604090205460ff16158015612b4d57506001600160a01b03851660009081526004602052604090205460ff16155b15612b5d57612ab5868683613271565b6001600160a01b03861660009081526004602052604090205460ff168015612b9d57506001600160a01b03851660009081526004602052604090205460ff165b15612bad57612ab5868683613299565b612bb8868683613271565b846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360800151604051612c0191815260200190565b60405180910390a36001600160a01b03861660009081526003602052604090205460ff161580612c525750828015612c5257506001600160a01b03851660009081526003602052604090205460ff16155b15612c6057612c60816132f5565b505050505050565b6001600160a01b0382166000908152601460205260409020805460ff19168215801591909117909155612cc7576001600160a01b03821660009081526004602052604090205460ff16612cbe57612cbe8261128c565b612cc7826124b8565b604080516001600160a01b038416815282151560208201527f9a05f836a81b64d2d3ee62b752e87947ab26a9fdcd5b2572b1744ae8499b3aac9101611280565b6001600160a01b03821661dead1415612d6c5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865206275726e206164647265736044820152607360f81b6064820152608401610b71565b6000612d7783611537565b905081811015612dd45760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610b71565b6000612ddf83613400565b6001600160a01b03851660009081526004602052604090205490915060ff1615612e31576001600160a01b03841660009081526002602052604081208054859290612e2b908490614087565b90915550505b6001600160a01b03841660009081526001602052604081208054839290612e59908490614087565b909155505061dead600090815260026020527f6a9609baa168169acaea398c4407efea4be641bb08e21e88806d9836fd9333cc8054859290612e9c908490613ed4565b909155505061dead600090815260016020527fb34209a263f6c38fe55f099e9e70f9d67e93982480ff3234a5e0108028ad164d8054839290612edf908490613ed4565b9250508190555082600c6000828254612ef89190614087565b9250508190555082600f6000828254612f119190613ed4565b9091555050604080516001600160a01b0386168152602081018590527fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5910160405180910390a160405183815261dead906001600160a01b038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a350505050565b6000600d548211156130075760405162461bcd60e51b815260206004820152602a60248201527f416d6f756e74206d757374206265206c657373207468616e20746f74616c207260448201526965666c656374696f6e7360b01b6064820152608401610b71565b6000613011613417565b905061301d8184613f14565b9392505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61307c613ada565b613084613ada565b8581526130938186868661343a565b61309d8186613655565b95945050505050565b6013546301000000900460ff16156110d95730600090815260026020526040902054601054811080159081906130df575060135460ff16155b801561310457506001600160a01b03831660009081526014602052604090205460ff16155b1561172057600954611720906001600160a01b03168361371a565b80516001600160a01b0384166000908152600260205260409020546131449190614087565b6001600160a01b03841660009081526002602090815260408083209390935560a084015160019091529190205461317b9190614087565b6001600160a01b0380851660009081526001602052604080822093909355610120840151918516815291909120546131b39190613ed4565b6001600160a01b039092166000908152600160205260409020919091555050565b60a08101516001600160a01b0384166000908152600160205260409020546131fc9190614087565b6001600160a01b03808516600090815260016020908152604080832094909455608085015192861682526002905291909120546132399190613ed4565b6001600160a01b0383166000908152600260209081526040808320939093556101208401516001909152919020546131b39190613ed4565b60a08101516001600160a01b03841660009081526001602052604090205461317b9190614087565b80516001600160a01b0384166000908152600260205260409020546132be9190614087565b6001600160a01b03841660009081526002602090815260408083209390935560a08401516001909152919020546131fc9190614087565b601354610100900460ff16156133775760208082015130600090815260029092526040822080549192909161332b908490613ed4565b909155505060c08101513060009081526001602052604081208054909190613354908490613ed4565b909155506133699050303383602001516126b1565b61337730826020015161169d565b6013546301000000900460ff16156133dd57606081015130600090815260026020526040812080549091906133ad908490613ed4565b909155505061010081015130600090815260016020526040812080549091906133d7908490613ed4565b90915550505b60135462010000900460ff16156110d9576110d98160e001518260400151613724565b60008061340b613417565b905061301d818461403c565b6000806000613424613753565b90925090506134338183613f14565b9250505090565b821561344c578351608085015261364f565b80156134dd578351600a54600954613475929163ffffffff90811691600160a01b9004166138d6565b60208501528351600a546009546134a4929163ffffffff600160401b909104811691600160e01b9004166138d6565b60608501528351600a546009546134d3929163ffffffff600160201b909104811691600160c01b9004166138d6565b604085015261361a565b811561361a57600a5460009063ffffffff600160201b820481169161350c91600160401b820481169116613eec565b6135169190613eec565b905063ffffffff811615613618578451601354600a5461356c9291849161354d9163ffffffff600160201b9091048116911661405b565b6135579190613f28565b600954600160a01b900463ffffffff166138d6565b60208601528451601354600a546135c0929184916135a19163ffffffff600160201b909104811691600160401b90041661405b565b6135ab9190613f28565b600954600160e01b900463ffffffff166138d6565b60608601528451601354600a54613612929184916135f39163ffffffff600160201b91829004811692919091041661405b565b6135fd9190613f28565b600954600160c01b900463ffffffff166138d6565b60408601525b505b60608401516040850151602086015186516136359190614087565b61363f9190614087565b6136499190614087565b60808501525b50505050565b600061365f613417565b835190915061366f90829061403c565b60a0840152811561368a5760a0830151610120840152505050565b825161369790829061403c565b60a084015260208301516136ac90829061403c565b60c084015260608301516136c190829061403c565b61010084015260408301516136d790829061403c565b60e0840181905261010084015160c085015160a08601519192916136fb9190614087565b6137059190614087565b61370f9190614087565b610120840152505050565b6110948282613911565b81600d546137329190614087565b600d8190555080600e600082825461374a9190613ed4565b90915550505050565b600d54600b546000918291825b6005548110156138a55782600160006005848154811061378257613782614136565b60009182526020808320909101546001600160a01b0316835282019290925260400190205411806137ed57508160026000600584815481106137c6576137c6614136565b60009182526020808320909101546001600160a01b03168352820192909252604001902054115b1561380357600d54600b54945094505050509091565b600160006005838154811061381a5761381a614136565b60009182526020808320909101546001600160a01b031683528201929092526040019020546138499084614087565b9250600260006005838154811061386257613862614136565b60009182526020808320909101546001600160a01b031683528201929092526040019020546138919083614087565b91508061389d816140d9565b915050613760565b50600b54600d546138b69190613f14565b8210156138cd57600d54600b549350935050509091565b90939092509050565b600060646138e583600a613f8e565b6138f563ffffffff86168761403c565b6138ff9190613f14565b6139099190613f14565b949350505050565b60135460ff16156139595760405162461bcd60e51b815260206004820152601260248201527121bab93932b73a363c9034b71039bbb0b81760711b6044820152606401610b71565b6013805460ff19166001179055604080516002808252606082018352600092602083019080368337019050509050308160008151811061399b5761399b614136565b6001600160a01b03928316602091820292909201810191909152600754604080516315ab88c960e31b81529051919093169263ad5c4648926004808301939192829003018186803b1580156139ef57600080fd5b505afa158015613a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a279190613b63565b81600181518110613a3a57613a3a614136565b6001600160a01b039283166020918202929092010152600754613a6091309116846126b1565b60075460405163791ac94760e01b81526001600160a01b039091169063791ac94790613a99908590600090869089904290600401613e63565b600060405180830381600087803b158015613ab357600080fd5b505af1158015613ac7573d6000803e3d6000fd5b50506013805460ff191690555050505050565b604051806101400160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b803563ffffffff81168114613b4157600080fd5b919050565b600060208284031215613b5857600080fd5b813561301d8161414c565b600060208284031215613b7557600080fd5b815161301d8161414c565b60008060408385031215613b9357600080fd5b8235613b9e8161414c565b91506020830135613bae8161414c565b809150509250929050565b600080600060608486031215613bce57600080fd5b8335613bd98161414c565b92506020840135613be98161414c565b929592945050506040919091013590565b60008060408385031215613c0d57600080fd5b8235613c188161414c565b915060208301358015158114613bae57600080fd5b60008060408385031215613c4057600080fd5b8235613c4b8161414c565b946020939093013593505050565b600060208284031215613c6b57600080fd5b5035919050565b600060208284031215613c8457600080fd5b61301d82613b2d565b60008060408385031215613ca057600080fd5b613ca983613b2d565b9150613cb760208401613b2d565b90509250929050565b600080600060608486031215613cd557600080fd5b613cde84613b2d565b9250613cec60208501613b2d565b91506040840135613cfc8161414c565b809150509250925092565b600060208083528351808285015260005b81811015613d3457858101830151858201604001528201613d18565b81811115613d46576000604083870101525b50601f01601f1916929092016040019392505050565b6020808252818101527f5461782072617465206d7573742062652067726561746572207468616e20302e604082015260600190565b6020808252602c908201527f546f74616c20746178206d757374206265206c6f776572207468616e2073656c60408201526b6c546178496e63726561736560a01b606082015260800190565b60208082526031908201527f54617820646563696d616c73206d757374206265206c657373207468616e207460408201527037b5b2b7103232b1b4b6b0b6399016901960791b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b81811015613eb35784516001600160a01b031683529383019391830191600101613e8e565b50506001600160a01b03969096166060850152505050608001529392505050565b60008219821115613ee757613ee76140f4565b500190565b600063ffffffff808316818516808303821115613f0b57613f0b6140f4565b01949350505050565b600082613f2357613f2361410a565b500490565b600063ffffffff80841680613f3f57613f3f61410a565b92169190910492915050565b600181815b80851115613f86578160001904821115613f6c57613f6c6140f4565b80851615613f7957918102915b93841c9390800290613f50565b509250929050565b600061301d63ffffffff841683600082613faa57506001610b41565b81613fb757506000610b41565b8160018114613fcd5760028114613fd757613ff3565b6001915050610b41565b60ff841115613fe857613fe86140f4565b50506001821b610b41565b5060208310610133831016604e8410600b8410161715614016575081810a610b41565b6140208383613f4b565b8060001904821115614034576140346140f4565b029392505050565b6000816000190483118215151615614056576140566140f4565b500290565b600063ffffffff8083168185168183048111821515161561407e5761407e6140f4565b02949350505050565b600082821015614099576140996140f4565b500390565b600181811c908216806140b257607f821691505b602082108114156140d357634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156140ed576140ed6140f4565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03811681146110d957600080fdfea264697066735822122090be67728d55074792bccfb54af13090a31ebe493008497f6038eb9a86b756cf64736f6c63430008070033

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

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