Contract Address Details

0xb132430d8Dca80f26D828d2d783E379AAcDc8272

Token
iDoge ($IDOGE)
Creator
0xb68a1a–6f7b3d at 0xe91c11–a9375f
Balance
277.125677748130154114 Doge
Tokens
Fetching tokens...
Transactions
766 Transactions
Transfers
119 Transfers
Gas Used
59,937,817
Last Balance Update
26548960
Contract name:
iDoge




Optimization enabled
true
Compiler version
v0.8.15+commit.e14f2714




Optimization runs
200
EVM Version
default




Verified at
2022-08-16T01:05:15.211532Z

Contract source code

/**

iDoge - The Smartest Doge 

https://t.me/iDogeDC


Total Supply: 100,000 / 100000
Max Wallet: 2% (2,000 Tokens) / 2000
Max Buy: 2% (2,000 Tokens) / 2000
Max Sell: 1% (1,000 Tokens) / 1000
Buy / Sell Tax: 10% 
- 3% Marketing
- 3% LP
- 3% Rewards
- 1% Development


*/

pragma solidity ^0.8.15;

// SPDX-License-Identifier: Unlicensed

interface IERC20 {
  function totalSupply() external view returns (uint256);
  function decimals() external view returns (uint8);
  function symbol() external view returns (string memory);
  function name() external view returns (string memory);
  function getOwner() external view returns (address);
  function balanceOf(address account) external view returns (uint256);
  function transfer(address recipient, uint256 amount) external returns (bool);
  function allowance(address _owner, address spender) external view returns (uint256);
  function approve(address spender, uint256 amount) external returns (bool);
  function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
  event Approval(address indexed owner, address indexed spender, uint256 value);
}


interface IUniswapV2ERC20 {
    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;
}

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

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);
    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);
    function createPair(address tokenA, address tokenB) external returns (address pair);
    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}

interface IUniswapV2Router01 {
    function 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 addLiquidityWDOGE(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountWDOGEMin,
        address to,
        uint deadline
    ) external payable returns (uint amountToken, uint amountWDOGE, 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 removeLiquidityWDOGE(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountWDOGEMin,
        address to,
        uint deadline
    ) external returns (uint amountToken, uint amountWDOGE);
    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 removeLiquidityWDOGEWithPermit(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountWDOGEMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountToken, uint amountWDOGE);
    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 swapExactWDOGEForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);
    function swapTokensForExactWDOGE(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapExactTokensForWDOGE(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapWDOGEForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);

    function factory() external pure returns (address);
    function WWDOGE() external pure returns (address);
    function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
    function getamountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
    function getamountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
    function getamountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
    function getamountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}

interface IUniswapV2Router02 is IUniswapV2Router01 {
    function removeLiquidityWDOGESupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountWDOGEMin,
        address to,
        uint deadline
    ) external returns (uint amountWDOGE);
    function removeLiquidityWDOGEWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountWDOGEMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountWDOGE);
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
    function swapExactWDOGEForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable;
    function swapExactTokensForWDOGESupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
}



/**
 * @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 {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        address msgSender = msg.sender;
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == msg.sender, "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 onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = 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 onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

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

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an WDOGE balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;

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

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

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

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

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

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            bytes32 lastvalue = set._values[lastIndex];

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

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

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

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

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

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

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

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

    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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

////////// Contract /////////////

contract iDoge is IERC20, Ownable
{
    using Address for address;
    using EnumerableSet for EnumerableSet.AddressSet;
    
    event antiBotBan(address indexed value);

    mapping (address => uint256) private _balances;
    mapping (address => mapping (address => uint256)) private _allowances;
    mapping (address => uint256) private _sellLock;
    mapping (address => uint256) private _buyLock;

    EnumerableSet.AddressSet private _excluded;
    EnumerableSet.AddressSet private _excludedFromSellLock;
    EnumerableSet.AddressSet private _excludedFromBuyLock;
    EnumerableSet.AddressSet private _excludedFromStaking;

    EnumerableSet.AddressSet private _isBlacklisted;

    //Token Info
    string public _name = "iDoge";
    string public _symbol = "$IDOGE";
    uint8 private constant _decimals = 9;
    uint256 public constant InitialSupply= 100000 * 10**_decimals;//equals 100,000 tokens 100000

    //Used for anti-bot autoblacklist
    uint256 private tradingEnabledAt; //DO NOT CHANGE, THIS IS FOR HOLDING A TIMESTAMP
    uint256 public autoBanTime = 20; // Set to the amount of time in seconds after enable trading you want addresses to be auto blacklisted if they buy/sell/transfer in this time.
    uint256 public enableAutoBlacklist = 0; //Leave 1 if using, set to 0 if not using.
    //Divider for the MaxBalance based on circulating Supply (2%)
    uint8 public constant BalanceLimitDivider=50;
    //Divider for sellLimit based on circulating Supply (2%))
    uint16 public constant SellLimitDivider=50;
    //Sellers get locked for MaxSellLockTime (put in seconds, works better especially if changing later) so they can't dump repeatedly
    uint16 public constant MaxSellLockTime= 0 seconds;
    //Buyers get locked for MaxBuyLockTime (put in seconds, works better especially if changing later) so they can't buy repeatedly
    uint16 public constant MaxBuyLockTime= 0 seconds;
    //The time Liquidity gets locked at start and prolonged once it gets released
    uint256 private constant DefaultLiquidityLockTime= 1800;
    //DevWallets
    address public Development=payable(0xb68A1a3aB92FE82adF7A4D01c307c328d16f7B3D);
    address public Marketing=payable(0xb68A1a3aB92FE82adF7A4D01c307c328d16f7B3D);
    //MainNet
    address private constant UniswapV2Router=0xa4EE06Ce40cb7e8c04E127c1F7D3dFB7F7039C81;

    //variables that track balanceLimit and sellLimit,
    //can be updated based on circulating supply and Sell- and BalanceLimitDividers
    uint256 private _circulatingSupply =InitialSupply;
    uint256 public  balanceLimit = _circulatingSupply;
    uint256 public  sellLimit = _circulatingSupply;
    uint256 private MaxBuy = 2000 * 10**_decimals; // 2,000 tokens
    
    //Tracks the current Taxes, different Taxes can be applied for buy/sell/transfer
    uint8 private _buyTax;
    uint8 private _sellTax;
    uint8 private _transferTax;

    uint8 private _burnTax;
    uint8 private _liquidityTax;
    uint8 private _stakingTax;

       
    address private _uniswapv2PairAddress; 
    IUniswapV2Router02 private  _uniswapv2Router;
    
    //Checks if address is in Team, is needed to give Team access even if contract is renounced
    //Team doesn't have access to critical Functions that could turn this into a Rugpull(Exept liquidity unlocks)
    function _isTeam(address addr) private view returns (bool){
        return addr==owner()||addr==Development||addr==Marketing;
    }

    //Constructor///////////

    constructor () {
        //contract creator gets 90% of the token to create LP-Pair
        uint256 deployerBalance=_circulatingSupply;
        _balances[msg.sender] = deployerBalance;
        emit Transfer(address(0), msg.sender, deployerBalance);
        // UniswapV2 Router
        _uniswapv2Router = IUniswapV2Router02(UniswapV2Router);
        //Creates a UniswapV2 Pair
        _uniswapv2PairAddress = IUniswapV2Factory(_uniswapv2Router.factory()).createPair(address(this), _uniswapv2Router.WWDOGE());
        
        //Sets Buy/Sell limits
        balanceLimit=InitialSupply/BalanceLimitDivider;
        sellLimit=InitialSupply/SellLimitDivider;

        //Sets sellLockTime
        sellLockTime=0;
        
        //Sets buyLockTime
        buyLockTime=0;

        //Set Starting Tax 
        
        _buyTax=10;
        _sellTax=10;
        _transferTax=10;

        _burnTax=0;
        _liquidityTax=30;
        _stakingTax=70;

        //Team wallets and deployer are excluded from Taxes
        _excluded.add(Development);
        _excluded.add(Marketing);
        _excluded.add(msg.sender);
        //excludes UniswapV2 Router, pair, contract and burn address from staking
        _excludedFromStaking.add(address(_uniswapv2Router));
        _excludedFromStaking.add(_uniswapv2PairAddress);
        _excludedFromStaking.add(address(this));
        _excludedFromStaking.add(0x000000000000000000000000000000000000dEaD);
    
    }

    //Transfer functionality///

    //transfer function, every transfer runs through this function
    function _transfer(address sender, address recipient, uint256 amount) private{
        require(sender != address(0), "Transfer from zero");
        require(recipient != address(0), "Transfer to zero");
        
        //Manually Excluded adresses are transfering tax and lock free
        bool isExcluded = (_excluded.contains(sender) || _excluded.contains(recipient));
        
        //Transactions from and to the contract are always tax and lock free
        bool isContractTransfer=(sender==address(this) || recipient==address(this));
        
        //transfers between UniswapV2Router and UniswapV2Pair are tax and lock free
        address uniswapv2Router=address(_uniswapv2Router);
        bool isLiquidityTransfer = ((sender == _uniswapv2PairAddress && recipient == uniswapv2Router) 
        || (recipient == _uniswapv2PairAddress && sender == uniswapv2Router));

        //differentiate between buy/sell/transfer to apply different taxes/restrictions
        bool isBuy=sender==_uniswapv2PairAddress|| sender == uniswapv2Router;
        bool isSell=recipient==_uniswapv2PairAddress|| recipient == uniswapv2Router;

        //Pick transfer
        if(isContractTransfer || isLiquidityTransfer || isExcluded){
            _feelessTransfer(sender, recipient, amount);
        }
        else{ 
            //once trading is enabled, it can't be turned off again
            require(tradingEnabled,"trading not yet enabled");
            _taxedTransfer(sender,recipient,amount,isBuy,isSell);
        }
    }
    //applies taxes, checks for limits, locks generates autoLP and stakingWDOGE, and autostakes
    function _taxedTransfer(address sender, address recipient, uint256 amount,bool isBuy,bool isSell) private{
        uint256 recipientBalance = _balances[recipient];
        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "Transfer exceeds balance");

        uint8 tax;
        if(isSell){
            if(!_excludedFromSellLock.contains(sender)){
                 //If seller sold less than sellLockTime(2h 50m) ago, sell is declined, can be disabled by Team         
                require(_sellLock[sender]<=block.timestamp||sellLockDisabled,"Seller in sellLock");
                //Sets the time sellers get locked(2 hours 50 mins by default)
                _sellLock[sender]=block.timestamp+sellLockTime;
            }
            //Sells can't exceed the sell limit(21,000 Tokens at start, can be updated to circulating supply)
            require(amount<=sellLimit,"Dump protection");
            require(_isBlacklisted.contains(sender) == false, "Address blacklisted!");

            if (block.timestamp <= tradingEnabledAt + autoBanTime && enableAutoBlacklist == 1) {
                _isBlacklisted.add(sender);
                emit antiBotBan(sender);
            }

            tax=_sellTax;


        } else if(isBuy){
            if(!_excludedFromBuyLock.contains(recipient)){
                 //If buyer bought less than buyLockTime(2h 50m) ago, buy is declined, can be disabled by Team         
                require(_buyLock[recipient]<=block.timestamp||buyLockDisabled,"Buyer in buyLock");
                //Sets the time buyers get locked(2 hours 50 mins by default)
                _buyLock[recipient]=block.timestamp+buyLockTime;
            }
            //Checks If the recipient balance(excluding Taxes) would exceed Balance Limit
            require(recipientBalance+amount<=balanceLimit,"whale protection");
            require(amount <= MaxBuy,"Tx amount exceeding max buy amount");
            require(_isBlacklisted.contains(recipient) == false, "Address blacklisted!");

            if (block.timestamp <= tradingEnabledAt + autoBanTime && enableAutoBlacklist == 1) {
                _isBlacklisted.add(recipient);
                emit antiBotBan(recipient);
            }

            tax=_buyTax;

        } else {//Transfer
            //withdraws WDOGE when sending less or equal to 1 Token
            //that way you can withdraw without connecting to any dApp.
            //might needs higher gas limit
            if(amount<=10**(_decimals)) claimWDOGE(sender);
            //Checks If the recipient balance(excluding Taxes) would exceed Balance Limit
            require(recipientBalance+amount<=balanceLimit,"whale protection");
            //Transfers are disabled in sell lock, this doesn't stop someone from transfering before
            //selling, but there is no satisfying solution for that, and you would need to pax additional tax
            if(!_excludedFromSellLock.contains(sender))
                require(_sellLock[sender]<=block.timestamp||sellLockDisabled,"Sender in Lock");
            
            require(_isBlacklisted.contains(sender) == false, "Sender address blacklisted!");
            require(_isBlacklisted.contains(recipient) == false, "Recipient address blacklisted!");

            if (block.timestamp <= tradingEnabledAt + autoBanTime && enableAutoBlacklist == 1) {
                _isBlacklisted.add(sender);
                emit antiBotBan(sender);
            }

            tax=_transferTax;

        }     
        //Swapping AutoLP and MarketingWDOGE is only possible if sender is not uniswapv2 pair, 
        //if its not manually disabled, if its not already swapping and if its a Sell to avoid
        // people from causing a large price impact from repeatedly transfering when theres a large backlog of Tokens
        if((sender!=_uniswapv2PairAddress)&&(!manualConversion)&&(!_isSwappingContractModifier)&&isSell)
            _swapContractToken();
        //Calculates the exact token amount for each tax
        uint256 tokensToBeBurnt=_calculateFee(amount, tax, _burnTax);
        //staking and liquidity Tax get treated the same, only during conversion they get split
        uint256 contractToken=_calculateFee(amount, tax, _stakingTax+_liquidityTax);
        //Subtract the Taxed Tokens from the amount
        uint256 taxedAmount=amount-(tokensToBeBurnt + contractToken);

        //Removes token and handles staking
        _removeToken(sender,amount);
        
        //Adds the taxed tokens to the contract wallet
        _balances[address(this)] += contractToken;
        //Burns tokens
        _circulatingSupply-=tokensToBeBurnt;

        //Adds token and handles staking
        _addToken(recipient, taxedAmount);
        
        emit Transfer(sender,recipient,taxedAmount);

    }

    //Feeless transfer only transfers and autostakes
    function _feelessTransfer(address sender, address recipient, uint256 amount) private{
        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "Transfer exceeds balance");
        //Removes token and handles staking
        _removeToken(sender,amount);
        //Adds token and handles staking
        _addToken(recipient, amount);
        
        emit Transfer(sender,recipient,amount);

    }
    //Calculates the token that should be taxed
    function _calculateFee(uint256 amount, uint8 tax, uint8 taxPercent) private pure returns (uint256) {
        return (amount*tax*taxPercent) / 10000;
    }

     //WDOGE Autostake/////////////////////////////////////////////////////////////////////////////////////////
       //Autostake uses the balances of each holder to redistribute auto generated WDOGE.
    //Each transaction _addToken and _removeToken gets called for the transaction amount
    //WithdrawWDOGE can be used for any holder to withdraw WDOGE at any time, like true Staking,
    //so unlike MRAT clones you can leave and forget your Token and claim after a while

    //lock for the withdraw
    bool private _isWithdrawing;
    //Multiplier to add some accuracy to profitPerShare
    uint256 private constant DistributionMultiplier = 2**64;
    //profit for each share a holder holds, a share equals a token.
    uint256 public profitPerShare;
    //the total reward distributed through staking, for tracking purposes
    uint256 public totalStakingReward;
    //the total payout through staking, for tracking purposes
    uint256 public totalPayouts;
    
  
    uint8 public marketingShare=50;
    //balance that is claimable by the team
    uint256 public marketingBalance;

    //Mapping of the already paid out(or missed) shares of each staker
    mapping(address => uint256) private alreadyPaidShares;
    //Mapping of shares that are reserved for payout
    mapping(address => uint256) private toBePaid;

    //Contract, uniswapv2 and burnAddress are excluded, other addresses like CEX
    //can be manually excluded, excluded list is limited to 30 entries to avoid a
    //out of gas exeption during sells
    function isExcludedFromStaking(address addr) public view returns (bool){
        return _excludedFromStaking.contains(addr);
    }

    //Check if address is blacklisted
    function isBlacklisted(address addr) public view returns (bool){
        return _isBlacklisted.contains(addr);
    }
    //Total shares equals circulating supply minus excluded Balances
    function _getTotalShares() public view returns (uint256){
        uint256 shares=_circulatingSupply;
        //substracts all excluded from shares, excluded list is limited to 30
        // to avoid creating a Honeypot through OutOfGas exeption
        for(uint i=0; i<_excludedFromStaking.length(); i++){
            shares-=_balances[_excludedFromStaking.at(i)];
        }
        return shares;
    }

    //adds Token to balances, adds new WDOGE to the toBePaid mapping and resets staking
    function _addToken(address addr, uint256 amount) private {
        //the amount of token after transfer
        uint256 newAmount=_balances[addr]+amount;
        
        if(isExcludedFromStaking(addr)){
           _balances[addr]=newAmount;
           return;
        }
        
        //gets the payout before the change
        uint256 payment=_newDividentsOf(addr);
        //resets dividents to 0 for newAmount
        alreadyPaidShares[addr] = profitPerShare * newAmount;
        //adds dividents to the toBePaid mapping
        toBePaid[addr]+=payment; 
        //sets newBalance
        _balances[addr]=newAmount;
    }
    
    
    //removes Token, adds WDOGE to the toBePaid mapping and resets staking
    function _removeToken(address addr, uint256 amount) private {
        //the amount of token after transfer
        uint256 newAmount=_balances[addr]-amount;
        
        if(isExcludedFromStaking(addr)){
           _balances[addr]=newAmount;
           return;
        }
        
        //gets the payout before the change
        uint256 payment=_newDividentsOf(addr);
        //sets newBalance
        _balances[addr]=newAmount;
        //resets dividents to 0 for newAmount
        alreadyPaidShares[addr] = profitPerShare * newAmount;
        //adds dividents to the toBePaid mapping
        toBePaid[addr]+=payment; 
    }
    
    
    //gets the not dividents of a staker that aren't in the toBePaid mapping 
    //returns wrong value for excluded accounts
    function _newDividentsOf(address staker) private view returns (uint256) {
        uint256 fullPayout = profitPerShare * _balances[staker];
        // if theres an overflow for some unexpected reason, return 0, instead of 
        // an exeption to still make trades possible
        if(fullPayout<alreadyPaidShares[staker]) return 0;
        return (fullPayout - alreadyPaidShares[staker]) / DistributionMultiplier;
    }

    //distributes WDOGE between marketing share and dividents 
    function _distributeStake(uint256 WDOGEamount) private {
        // Deduct marketing Tax
        uint256 marketingSplit = (WDOGEamount * marketingShare) / 100;
        uint256 amount = WDOGEamount - marketingSplit;

       marketingBalance+=marketingSplit;
       
        if (amount > 0) {
            totalStakingReward += amount;
            uint256 totalShares=_getTotalShares();
            //when there are 0 shares, add everything to marketing budget
            if (totalShares == 0) {
                marketingBalance += amount;
            }else{
                //Increases profit per share based on current total shares
                profitPerShare += ((amount * DistributionMultiplier) / totalShares);
            }
        }
    }
    event OnWithdrawWDOGE(uint256 amount, address recipient);
    
    //withdraws all dividents of address
    function claimWDOGE(address addr) private{
        require(!_isWithdrawing);
        _isWithdrawing=true;
        uint256 amount;
        if(isExcludedFromStaking(addr)){
            //if excluded just withdraw remaining toBePaid WDOGE
            amount=toBePaid[addr];
            toBePaid[addr]=0;
        }
        else{
            uint256 newAmount=_newDividentsOf(addr);
            //sets payout mapping to current amount
            alreadyPaidShares[addr] = profitPerShare * _balances[addr];
            //the amount to be paid 
            amount=toBePaid[addr]+newAmount;
            toBePaid[addr]=0;
        }
        if(amount==0){//no withdraw if 0 amount
            _isWithdrawing=false;
            return;
        }


        totalPayouts+=amount;
        address[] memory path = new address[](2);
        path[0] = _uniswapv2Router.WWDOGE(); //WDOGE
        path[1] = RewardsAddress; //USDC Rewards - Option to enable.

        _uniswapv2Router.swapExactWDOGEForTokensSupportingFeeOnTransferTokens{value: amount}(
        0,
        path,
        addr,
        block.timestamp);
        
        emit OnWithdrawWDOGE(amount, addr);
        _isWithdrawing=false;
    }
        //Launch Rewards Address - Can be Changed - Rewards not enabled at launch.
    address public RewardsAddress=(0xA0eB9a6063Df850F611AA69C60025c7f8eB4d6ee); // DogeShiba
    //Swap Contract Tokens//////////////////////////////////////////////////////////////////////////////////



    //tracks auto generated WDOGE, useful for ticker etc
    uint256 public totalLPWDOGE;
    //Locks the swap if already swapping
    bool private _isSwappingContractModifier;
    modifier lockTheSwap {
        _isSwappingContractModifier = true;
        _;
        _isSwappingContractModifier = false;
    }
    uint256 currentAmountToSwap = 800 * 10**_decimals;  // 800,000 tokens (0.8%)
    //swaps the token on the contract for Marketing WDOGE and LP Token.
    //always swaps the sellLimit of token to avoid a large price impact
    function _swapContractToken() private lockTheSwap{
        uint256 contractBalance=_balances[address(this)];
        uint16 totalTax=_liquidityTax+_stakingTax;
        uint256 tokenToSwap = currentAmountToSwap;
        //only swap if contractBalance is larger than tokenToSwap, and totalTax is unequal to 0
        if(contractBalance<tokenToSwap||totalTax==0){
            return;
        }
        //splits the token in TokenForLiquidity and tokenForMarketing
        uint256 tokenForLiquidity=(tokenToSwap*_liquidityTax)/totalTax;
        uint256 tokenForMarketing= tokenToSwap-tokenForLiquidity;

        //splits tokenForLiquidity in 2 halves
        uint256 liqToken=tokenForLiquidity/2;
        uint256 liqWDOGEToken=tokenForLiquidity-liqToken;

        //swaps marktetingToken and the liquidity token half for WDOGE
        uint256 swapToken=liqWDOGEToken+tokenForMarketing;
        //Gets the initial WDOGE balance, so swap won't touch any staked WDOGE
        uint256 initialWDOGEBalance = address(this).balance;
        _swapTokenForWDOGE(swapToken);
        uint256 newWDOGE=(address(this).balance - initialWDOGEBalance);
        //calculates the amount of WDOGE belonging to the LP-Pair and converts them to LP
        uint256 liqWDOGE = (newWDOGE*liqWDOGEToken)/swapToken;
        _addLiquidity(liqToken, liqWDOGE);
        //Get the WDOGE balance after LP generation to get the
        //exact amount of token left for Staking
        uint256 distributeWDOGE=(address(this).balance - initialWDOGEBalance);
        //distributes remaining WDOGE between stakers and Marketing
        _distributeStake(distributeWDOGE);
    }
    //swaps tokens on the contract for WDOGE
    function _swapTokenForWDOGE(uint256 amount) private {
        _approve(address(this), address(_uniswapv2Router), amount);
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = _uniswapv2Router.WWDOGE();

        _uniswapv2Router.swapExactTokensForWDOGESupportingFeeOnTransferTokens(
            amount,
            0,
            path,
            address(this),
            block.timestamp
        );
    }
    //Adds Liquidity directly to the contract where LP are locked(unlike safemoon forks, that transfer it to the owner)
    function _addLiquidity(uint256 tokenamount, uint256 dogeamount) private {
        totalLPWDOGE+=dogeamount;
        _approve(address(this), address(_uniswapv2Router), tokenamount);
        _uniswapv2Router.addLiquidityWDOGE{value: dogeamount}(
            address(this),
            tokenamount,
            0,
            0,
            address(this),
            block.timestamp
        );
    }

    //public functions /////////////////////////////////////////////////////////////////////////////////////

    function getLiquidityReleaseTimeInSeconds() public view returns (uint256){
        if(block.timestamp<_liquidityUnlockTime){
            return _liquidityUnlockTime-block.timestamp;
        }
        return 0;
    }

    function getBurnedTokens() public view returns(uint256){
        return (InitialSupply-_circulatingSupply)/10**_decimals;
    }

    function getLimits() public view returns(uint256 balance, uint256 sell){
        return(balanceLimit/10**_decimals, sellLimit/10**_decimals);
    }

    function getTaxes() public view returns(uint256 burnTax,uint256 liquidityTax,uint256 marketingTax, uint256 buyTax, uint256 sellTax, uint256 transferTax){
        return (_burnTax,_liquidityTax,_stakingTax,_buyTax,_sellTax,_transferTax);
    }

    //How long is a given address still locked from selling
    //function getAddressSellLockTimeInSeconds(address AddressToCheck) public view returns (uint256){
    //   uint256 lockTime=_sellLock[AddressToCheck];
    //   if(lockTime<=block.timestamp)
    //   {
    //       return 0;
    //   }
    //   return lockTime-block.timestamp;
    //}
    //function getSellLockTimeInSeconds() public view returns(uint256){
    //    return sellLockTime;
    //}
    
    function getcurrentAmountToSwap() public view returns (uint256){
          return currentAmountToSwap;
    }

    //How long is a given address still locked from buying - not used
    //function getAddressBuyLockTimeInSeconds(address AddressToCheck) public view returns (uint256){
    //   uint256 lockTime=_buyLock[AddressToCheck];
    //   if(lockTime<=block.timestamp)
    //   {
    //       return 0;
    //   }
    //   return lockTime-block.timestamp;
    //}
    //function getBuyLockTimeInSeconds() public view returns(uint256){
    //    return buyLockTime;
    //}
    
    //Functions every wallet can call - no sell lock in isde
    //Resets sell lock of caller to the default sellLockTime should something go very wrong
    //function AddressResetSellLock() public{
    //    _sellLock[msg.sender]=block.timestamp+sellLockTime;
    //}
    
    //Resets buy lock of caller to the default buyLockTime should something go very wrong - no buy lock in usde
 //   function AddressResetBuyLock() public{
 //       _buyLock[msg.sender]=block.timestamp+buyLockTime;
    
 //   }

        //withdraws dividents of sender
    function Rewards() public{
        claimWDOGE(msg.sender);
    }

    function getDividents(address addr) public view returns (uint256){
        if(isExcludedFromStaking(addr)) return toBePaid[addr];
        return _newDividentsOf(addr)+toBePaid[addr];
    }

    //Settings//////////////////////////////////////////////////////////////////////////////////////////////
 
    bool public sellLockDisabled;
    uint256 public sellLockTime;
    bool public buyLockDisabled;
    uint256 public buyLockTime;
    bool public manualConversion; 

    function CollectMarketingWDOGE() public onlyOwner{
        uint256 amount=marketingBalance;
        marketingBalance=0;
        payable(Development).transfer((amount*50) / 100);
        payable(Marketing).transfer((amount*50) / 100);
    } 
    function TeamCollectXMarketingWDOGE(uint256 amount) public onlyOwner{
        require(amount<=marketingBalance);
        marketingBalance-=amount;
        payable(Development).transfer((amount*50) / 100);
        payable(Marketing).transfer((amount*50) / 100);
    } 

    //switches autoLiquidity and marketing WDOGE generation during transfers
    function TeamSwitchManualWDOGEConversion(bool manual) public onlyOwner{
        manualConversion=manual;
    }
    
    function TeamChangeMaxBuy(uint256 newMaxBuy) public onlyOwner{
      MaxBuy=newMaxBuy * 10**_decimals;
    }
    
    function TeamChangeDevelopment(address newDevelopment) public onlyOwner{
      Development=payable(newDevelopment);
    }

    function TeamChangeMarketing(address newMarketing) public onlyOwner{
      Marketing=payable(newMarketing);
    }

    function TeamChangeRewardsAddress(address newRewardsAddress) public onlyOwner{
      RewardsAddress=(newRewardsAddress);
    }

    function updateTokenDetails(string memory newName, string memory newSymbol) public onlyOwner {
        _name = newName;
        _symbol = newSymbol;
    }



    //Disables the timeLock after selling for everyone
    function TeamDisableSellLock(bool disabled) public onlyOwner{
        sellLockDisabled=disabled;
    }
    
    //Disables the timeLock after buying for everyone
    function TeamDisableBuyLock(bool disabled) public onlyOwner{
        buyLockDisabled=disabled;
    }

    //Sets SellLockTime, needs to be lower than MaxSellLockTime
    function TeamSetSellLockTime(uint256 sellLockSeconds)public onlyOwner{
            require(sellLockSeconds<=MaxSellLockTime,"Sell Lock time too high");
            sellLockTime=sellLockSeconds;
    } 
    
    //Sets BuyLockTime, needs to be lower than MaxBuyLockTime
    function TeamSetBuyLockTime(uint256 buyLockSeconds)public onlyOwner{
            require(buyLockSeconds<=MaxBuyLockTime,"Buy Lock time too high");
            buyLockTime=buyLockSeconds;
    } 

    //Allows CA owner to change how much the contract sells to prevent massive contract sells as the token grows.
    function TeamUpdateAmountToSwap(uint256 newSwapAmount) public onlyOwner{
        currentAmountToSwap = newSwapAmount;
    }
    
    //Allows wallet exclusion to be added after launch
    function AddWalletExclusion(address exclusionAdd) public onlyOwner{
        _excluded.add(exclusionAdd);
    }
    
    //Sets Taxes
    function TeamSetTaxes(uint8 burnTaxes, uint8 liquidityTaxes, uint8 stakingTaxes,uint8 buyTax, uint8 sellTax, uint8 transferTax) public onlyOwner{
        uint8 totalTax=burnTaxes+liquidityTaxes+stakingTaxes;
        require(totalTax==100, "burn+liq+marketing needs to equal 100%");

        _burnTax=burnTaxes;
        _liquidityTax=liquidityTaxes;
        _stakingTax=stakingTaxes;
        
        _buyTax=buyTax;
        _sellTax=sellTax;
        _transferTax=transferTax;
    }

    //How much of the staking tax should be allocated for marketing
    function TeamChangeMarketingShare(uint8 newShare) public onlyOwner{
        require(newShare<=100); 
        marketingShare=newShare;
    }
    //manually converts contract token to LP and staking WDOGE
    function TeamCreateLPandWDOGE() public onlyOwner{
    _swapContractToken();
    }
    
     //Limits need to be at least target, to avoid setting value to 0(avoid potential Honeypot)
    function TeamUpdateLimits(uint256 newBalanceLimit, uint256 newSellLimit) public onlyOwner{
        //SellLimit needs to be below 1% to avoid a Large Price impact when generating auto LP
        require(newSellLimit<_circulatingSupply/100);
        //Adds decimals to limits
        newBalanceLimit=newBalanceLimit*10**_decimals;
        newSellLimit=newSellLimit*10**_decimals;
        //Calculates the target Limits based on supply
        uint256 targetBalanceLimit=_circulatingSupply/BalanceLimitDivider;
        uint256 targetSellLimit=_circulatingSupply/SellLimitDivider;

        require((newBalanceLimit>=targetBalanceLimit), 
        "newBalanceLimit needs to be at least target");
        require((newSellLimit>=targetSellLimit), 
        "newSellLimit needs to be at least target");

        balanceLimit = newBalanceLimit;
        sellLimit = newSellLimit;     
    }

    //Adds address to blacklist and prevents sells, buys or transfers.
    function addAddressToBlacklist(address blacklistedAddress) external onlyOwner {
        _isBlacklisted.add(blacklistedAddress);
    }

    //Remove address from blacklist and allow sells, buys or transfers.
    function removeAddressFromBlacklist(address blacklistedAddress) external onlyOwner {
        _isBlacklisted.remove(blacklistedAddress);
    }
    
    //Setup Functions///////////////////////////////////////////////////////////////////////////////////////
    
    bool public tradingEnabled;
    address private _liquidityTokenAddress;
    //Enables trading for everyone
    function SetupEnableTrading() public onlyOwner{
        tradingEnabled=true;
        tradingEnabledAt=block.timestamp;
    }

    //Sets up the LP-Token Address required for LP Release
    function SetupLiquidityTokenAddress(address liquidityTokenAddress) public onlyOwner{
        _liquidityTokenAddress=liquidityTokenAddress;
    }

    //Liquidity Lock////////////////////////////////////////////////////////////////////////////////////////
    //the timestamp when Liquidity unlocks
    uint256 private _liquidityUnlockTime;

    function TeamExtendLiquidityLock(uint256 secondsUntilUnlock) public onlyOwner{
        _prolongLiquidityLock(secondsUntilUnlock+block.timestamp);
    }
    function _prolongLiquidityLock(uint256 newUnlockTime) private{
        // require new unlock time to be longer than old one
        require(newUnlockTime>_liquidityUnlockTime);
        _liquidityUnlockTime=newUnlockTime;
    }

    //Release Liquidity Tokens generated from LP tax to owner once unlock time is over so they can be locked in liquidity locker.
    function ReleaseTaxedLiquidityToLock() public onlyOwner {
        //Only callable if liquidity Unlock time is over
        require(block.timestamp >= _liquidityUnlockTime, "Not yet unlocked");
        
        IUniswapV2ERC20 liquidityToken = IUniswapV2ERC20(_liquidityTokenAddress);
        uint256 amount = liquidityToken.balanceOf(address(this));

        //Liquidity release if something goes wrong at start
        liquidityToken.transfer(Development, amount);
        
    }
    //Removes Liquidity once unlock Time is over - Depreciated function - would add to staking pool for distribution.
    /*
        function REM(bool addToStaking) public onlyOwner{
        //Only callable if liquidity Unlock time is over
        require(block.timestamp >= _liquidityUnlockTime, "Not yet unlocked");
        _liquidityUnlockTime=block.timestamp+DefaultLiquidityLockTime;
        IUniswapV2ERC20 liquidityToken = IUniswapV2ERC20(_liquidityTokenAddress);
        uint256 amount = liquidityToken.balanceOf(address(this));

        liquidityToken.approve(address(_uniswapv2Router),amount);
        //Removes Liquidity and either distributes liquidity WDOGE to stakers, or 
        // adds them to marketing Balance
        //Token will be converted
        //to Liquidity and Staking WDOGE again
        uint256 initialWDOGEBalance = address(this).balance;
        _uniswapv2Router.removeLiquidityWDOGESupportingFeeOnTransferTokens(
            address(this),
            amount,
            0,
            0,
            address(this),
            block.timestamp
            );
        uint256 newWDOGEBalance = address(this).balance-initialWDOGEBalance;
        if(addToStaking){
            _distributeStake(newWDOGEBalance);
        }
        else{
            marketingBalance+=newWDOGEBalance;
        }

    }
    */
    //Releases all remaining WDOGE on the contract wallet, so WDOGE wont be burned
    function TeamCollectRemainingWDOGE() public onlyOwner{
        require(block.timestamp >= _liquidityUnlockTime, "Not yet unlocked");
        _liquidityUnlockTime=block.timestamp+DefaultLiquidityLockTime;
        (bool sent,) =Development.call{value: (address(this).balance)}("");
        require(sent);
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////
    //external//////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////

    receive() external payable {}
    fallback() external payable {}
    // IERC20

    function getOwner() external view override returns (address) {
        return owner();
    }

    function name() external view override returns (string memory) { 
        return _name; 
    }
    function symbol() external view override returns (string memory) 
    { return _symbol; 
    }
    function decimals() external pure override returns (uint8) {
        return _decimals;
    }

    function totalSupply() external view override returns (uint256) {
        return _circulatingSupply;
    }

    function balanceOf(address account) external view override returns (uint256) {
        return _balances[account];
    }

    function transfer(address recipient, uint256 amount) external override returns (bool) {
        _transfer(msg.sender, recipient, amount);
        return true;
    }

    function allowance(address _owner, address spender) external view override returns (uint256) {
        return _allowances[_owner][spender];
    }

    function approve(address spender, uint256 amount) external override returns (bool) {
        _approve(msg.sender, spender, amount);
        return true;
    }
    function _approve(address owner, address spender, uint256 amount) private {
        require(owner != address(0), "Approve from zero");
        require(spender != address(0), "Approve to zero");

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

    function transferFrom(address sender, address recipient, uint256 amount) external override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][msg.sender];
        require(currentAllowance >= amount, "Transfer > allowance");

        _approve(sender, msg.sender, currentAllowance - amount);
        return true;
    }

    // IERC20 - Helpers

    function increaseAllowance(address spender, uint256 addedValue) external returns (bool) {
        _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);
        return true;
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool) {
        uint256 currentAllowance = _allowances[msg.sender][spender];
        require(currentAllowance >= subtractedValue, "<0 allowance");

        _approve(msg.sender, spender, currentAllowance - subtractedValue);
        return true;
    }

}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OnWithdrawWDOGE","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"address","name":"recipient","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"antiBotBan","inputs":[{"type":"address","name":"value","internalType":"address","indexed":true}],"anonymous":false},{"type":"fallback","stateMutability":"payable"},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"AddWalletExclusion","inputs":[{"type":"address","name":"exclusionAdd","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"BalanceLimitDivider","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"CollectMarketingWDOGE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"Development","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"InitialSupply","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"Marketing","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"MaxBuyLockTime","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"MaxSellLockTime","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"ReleaseTaxedLiquidityToLock","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"Rewards","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"RewardsAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"SellLimitDivider","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"SetupEnableTrading","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"SetupLiquidityTokenAddress","inputs":[{"type":"address","name":"liquidityTokenAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamChangeDevelopment","inputs":[{"type":"address","name":"newDevelopment","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamChangeMarketing","inputs":[{"type":"address","name":"newMarketing","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamChangeMarketingShare","inputs":[{"type":"uint8","name":"newShare","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamChangeMaxBuy","inputs":[{"type":"uint256","name":"newMaxBuy","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamChangeRewardsAddress","inputs":[{"type":"address","name":"newRewardsAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamCollectRemainingWDOGE","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamCollectXMarketingWDOGE","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamCreateLPandWDOGE","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamDisableBuyLock","inputs":[{"type":"bool","name":"disabled","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamDisableSellLock","inputs":[{"type":"bool","name":"disabled","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamExtendLiquidityLock","inputs":[{"type":"uint256","name":"secondsUntilUnlock","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamSetBuyLockTime","inputs":[{"type":"uint256","name":"buyLockSeconds","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamSetSellLockTime","inputs":[{"type":"uint256","name":"sellLockSeconds","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamSetTaxes","inputs":[{"type":"uint8","name":"burnTaxes","internalType":"uint8"},{"type":"uint8","name":"liquidityTaxes","internalType":"uint8"},{"type":"uint8","name":"stakingTaxes","internalType":"uint8"},{"type":"uint8","name":"buyTax","internalType":"uint8"},{"type":"uint8","name":"sellTax","internalType":"uint8"},{"type":"uint8","name":"transferTax","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamSwitchManualWDOGEConversion","inputs":[{"type":"bool","name":"manual","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamUpdateAmountToSwap","inputs":[{"type":"uint256","name":"newSwapAmount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"TeamUpdateLimits","inputs":[{"type":"uint256","name":"newBalanceLimit","internalType":"uint256"},{"type":"uint256","name":"newSellLimit","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"_getTotalShares","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"_name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"_symbol","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addAddressToBlacklist","inputs":[{"type":"address","name":"blacklistedAddress","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"autoBanTime","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceLimit","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"buyLockDisabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"buyLockTime","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"enableAutoBlacklist","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getBurnedTokens","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getDividents","inputs":[{"type":"address","name":"addr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"balance","internalType":"uint256"},{"type":"uint256","name":"sell","internalType":"uint256"}],"name":"getLimits","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getLiquidityReleaseTimeInSeconds","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getOwner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"burnTax","internalType":"uint256"},{"type":"uint256","name":"liquidityTax","internalType":"uint256"},{"type":"uint256","name":"marketingTax","internalType":"uint256"},{"type":"uint256","name":"buyTax","internalType":"uint256"},{"type":"uint256","name":"sellTax","internalType":"uint256"},{"type":"uint256","name":"transferTax","internalType":"uint256"}],"name":"getTaxes","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getcurrentAmountToSwap","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isBlacklisted","inputs":[{"type":"address","name":"addr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isExcludedFromStaking","inputs":[{"type":"address","name":"addr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"manualConversion","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"marketingBalance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"marketingShare","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"profitPerShare","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeAddressFromBlacklist","inputs":[{"type":"address","name":"blacklistedAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"sellLimit","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"sellLockDisabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"sellLockTime","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalLPWDOGE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalPayouts","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalStakingReward","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"tradingEnabled","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"sender","internalType":"address"},{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateTokenDetails","inputs":[{"type":"string","name":"newName","internalType":"string"},{"type":"string","name":"newSymbol","internalType":"string"}]},{"type":"receive","stateMutability":"payable"}]
            

Contract Creation Code

0x60c0604052600560809081526469446f676560d81b60a052600f9062000026908262000612565b506040805180820190915260068152652449444f474560d01b602082015260109062000053908262000612565b50601460128190556000601355805473b68a1a3ab92fe82adf7a4d01c307c328d16f7b3d6001600160a01b03199182168117909255601580549091169091179055620000a26009600a620007f1565b620000b190620186a062000802565b60168190556017819055601855620000cc6009600a620007f1565b620000da906107d062000802565b601955601f805460ff19166032179055602380546001600160a01b03191673a0eb9a6063df850f611aa69c60025c7f8eb4d6ee1790556200011e6009600a620007f1565b6200012c9061032062000802565b6026553480156200013c57600080fd5b50600080546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350601654336000818152600160209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3601b80546001600160a01b03191673a4ee06ce40cb7e8c04e127c1f7d3dfb7f7039c819081179091556040805163c45a015560e01b8152905163c45a0155916004808201926020929091908290030181865afa1580156200022a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000250919062000824565b6001600160a01b031663c9c6539630601b60009054906101000a90046001600160a01b03166001600160a01b0316634ed154606040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002b3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002d9919062000824565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af115801562000327573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200034d919062000824565b601a80546001600160a01b0392909216660100000000000002600160301b600160d01b031990921691909117905560326200038b6009600a620007f1565b6200039a90620186a062000802565b620003a6919062000856565b6017556032620003b96009600a620007f1565b620003c890620186a062000802565b620003d4919062000856565b60185560006028819055602a55601a805465ffffffffffff191665461e000a0a0a1790556014546200041e906005906001600160a01b0316620004fb602090811b62001fa017901c565b5060155462000445906005906001600160a01b0316620004fb602090811b62001fa017901c565b5062000461336005620004fb60201b62001fa01790919060201c565b50601b546200048890600b906001600160a01b0316620004fb602090811b62001fa017901c565b50620004b9601a60069054906101000a90046001600160a01b0316600b620004fb60201b62001fa01790919060201c565b50620004d530600b620004fb60201b62001fa01790919060201c565b50620004f361dead600b620004fb60201b62001fa01790919060201c565b505062000879565b600062000512836001600160a01b0384166200051b565b90505b92915050565b6000818152600183016020526040812054620005645750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000515565b50600062000515565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200059857607f821691505b602082108103620005b957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200060d57600081815260208120601f850160051c81016020861015620005e85750805b601f850160051c820191505b818110156200060957828155600101620005f4565b5050505b505050565b81516001600160401b038111156200062e576200062e6200056d565b62000646816200063f845462000583565b84620005bf565b602080601f8311600181146200067e5760008415620006655750858301515b600019600386901b1c1916600185901b17855562000609565b600085815260208120601f198616915b82811015620006af578886015182559484019460019091019084016200068e565b5085821015620006ce5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000735578160001904821115620007195762000719620006de565b808516156200072757918102915b93841c9390800290620006f9565b509250929050565b6000826200074e5750600162000515565b816200075d5750600062000515565b81600181146200077657600281146200078157620007a1565b600191505062000515565b60ff841115620007955762000795620006de565b50506001821b62000515565b5060208310610133831016604e8410600b8410161715620007c6575081810a62000515565b620007d28383620006f4565b8060001904821115620007e957620007e9620006de565b029392505050565b60006200051260ff8416836200073d565b60008160001904831182151516156200081f576200081f620006de565b500290565b6000602082840312156200083757600080fd5b81516001600160a01b03811681146200084f57600080fd5b9392505050565b6000826200087457634e487b7160e01b600052601260045260246000fd5b500490565b613eb280620008896000396000f3fe60806040526004361061041b5760003560e01c806373ddf08e1161021c578063c3a3c03211610122578063e2fd002a116100b0578063f0cc761211610077578063f0cc761214610c73578063f2c816ae14610c93578063f2fde38b14610cb3578063f88b0e4614610cd3578063fe575a8714610ce957005b8063e2fd002a14610bf3578063e68f136a14610c13578063e69e03ee14610c33578063ef12a33014610c48578063f00df36514610c5d57005b8063d11edf74116100f4578063d11edf7414610b38578063d28d885214610b58578063d51f383b14610b6d578063db886f2314610b8d578063dd62ed3e14610bad57005b8063c3a3c03214610ace578063c3f4f54f14610ae3578063cd979a7e14610af8578063d0291d6614610b1857005b8063951ed3fb116101aa578063b09f126611610171578063b09f126614610a44578063b58a56cd14610a59578063b766a38614610a79578063c054f2f414610a99578063c280895414610ab957005b8063951ed3fb146109af57806395d89b41146109cf5780639fa62d5f146109e4578063a457c2d714610a04578063a9059cbb14610a2457005b806386d0ada8116101ee57806386d0ada81461090b578063887c60fb14610925578063893d20e81461093f5780638da5cb5b1461097157806394e8075d1461098f57005b806373ddf08e146108aa578063762bb282146108ca5780637b9e987a146108e05780638650e92a146108f557005b80634089b170116103215780635b80f625116102af5780636ea4caab116102765780636ea4caab146107f55780636f89e4091461081557806370a082311461083f578063715018a6146108755780637335307b1461088a57005b80635b80f625146107965780635c69f69014610629578063643daaea146107ab57806368ba3d7a146107cb5780636a6bc5ad146107e057005b80634cdaf0ae116102f35780634cdaf0ae146107145780634f91e48c1461073457806357ad67d11461074a57806357b1c4f21461076a57806358e553651461078057005b80634089b170146106b457806344f3c83a146106ca578063459a7484146106e05780634ada218b146106f557005b80632973ef2d116103a95780633478154b116103705780633478154b1461062957806335e82f3a1461063e578063395093511461065e5780633d2bdb1d1461067e5780633da56f181461069e57005b80632973ef2d1461055d5780633054f8a3146105c6578063311a8697146105e0578063313ce567146105f557806332ac487f1461060957005b806314e91377116103ed57806314e91377146104d357806318160ddd146104f35780631eb25d131461051257806323b872dd14610527578063269a6aae1461054757005b806306fdde031461042457806309218ee71461044f578063095ea7b31461047b5780630fd99e16146104ab57005b3661042257005b005b34801561043057600080fd5b50610439610d09565b60405161044691906136b5565b60405180910390f35b34801561045b57600080fd5b50601f546104699060ff1681565b60405160ff9091168152602001610446565b34801561048757600080fd5b5061049b61049636600461371f565b610d9b565b6040519015158152602001610446565b3480156104b757600080fd5b506104c0603281565b60405161ffff9091168152602001610446565b3480156104df57600080fd5b506104226104ee366004613759565b610db2565b3480156104ff57600080fd5b506016545b604051908152602001610446565b34801561051e57600080fd5b50610504610e07565b34801561053357600080fd5b5061049b610542366004613776565b610e23565b34801561055357600080fd5b5061050460125481565b34801561056957600080fd5b50601a546040805160ff6301000000840481168252640100000000840481166020830152600160281b84048116928201929092528183166060820152610100830482166080820152620100009092041660a082015260c001610446565b3480156105d257600080fd5b5060295461049b9060ff1681565b3480156105ec57600080fd5b50610469603281565b34801561060157600080fd5b506009610469565b34801561061557600080fd5b506105046106243660046137b7565b610eba565b34801561063557600080fd5b506104c0600081565b34801561064a57600080fd5b506104226106593660046137b7565b610f12565b34801561066a57600080fd5b5061049b61067936600461371f565b610f5a565b34801561068a57600080fd5b506104226106993660046137d4565b610f91565b3480156106aa57600080fd5b5061050460135481565b3480156106c057600080fd5b50610504601e5481565b3480156106d657600080fd5b50610504602a5481565b3480156106ec57600080fd5b5061042261108d565b34801561070157600080fd5b50602b5461049b90610100900460ff1681565b34801561072057600080fd5b5061042261072f3660046137b7565b6110d0565b34801561074057600080fd5b5061050460185481565b34801561075657600080fd5b50610422610765366004613803565b611133565b34801561077657600080fd5b5061050460245481565b34801561078c57600080fd5b5061050460205481565b3480156107a257600080fd5b50602654610504565b3480156107b757600080fd5b506104226107c63660046137d4565b611266565b3480156107d757600080fd5b506104226112b4565b3480156107ec57600080fd5b50610422611312565b34801561080157600080fd5b506104226108103660046137d4565b6113ff565b34801561082157600080fd5b5061082a611454565b60408051928352602083019190915201610446565b34801561084b57600080fd5b5061050461085a3660046137b7565b6001600160a01b031660009081526001602052604090205490565b34801561088157600080fd5b50610422611491565b34801561089657600080fd5b5061049b6108a53660046137b7565b611514565b3480156108b657600080fd5b506104226108c5366004613877565b611521565b3480156108d657600080fd5b5061050460175481565b3480156108ec57600080fd5b50610422611581565b34801561090157600080fd5b50610504601c5481565b34801561091757600080fd5b50602b5461049b9060ff1681565b34801561093157600080fd5b5060275461049b9060ff1681565b34801561094b57600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610446565b34801561097d57600080fd5b506000546001600160a01b0316610959565b34801561099b57600080fd5b50601454610959906001600160a01b031681565b3480156109bb57600080fd5b506104226109ca366004613759565b6115d4565b3480156109db57600080fd5b50610439611620565b3480156109f057600080fd5b506104226109ff366004613892565b61162f565b348015610a1057600080fd5b5061049b610a1f36600461371f565b6117b1565b348015610a3057600080fd5b5061049b610a3f36600461371f565b61182d565b348015610a5057600080fd5b5061043961183a565b348015610a6557600080fd5b50610422610a743660046137b7565b6118c8565b348015610a8557600080fd5b50610422610a94366004613759565b611923565b348015610aa557600080fd5b50602354610959906001600160a01b031681565b348015610ac557600080fd5b5061042261196f565b348015610ada57600080fd5b50610504611978565b348015610aef57600080fd5b50610504611998565b348015610b0457600080fd5b50610422610b133660046137b7565b6119d6565b348015610b2457600080fd5b50610422610b33366004613957565b611a1a565b348015610b4457600080fd5b50610422610b533660046137d4565b611a71565b348015610b6457600080fd5b50610439611aaf565b348015610b7957600080fd5b50610422610b883660046137d4565b611abc565b348015610b9957600080fd5b50601554610959906001600160a01b031681565b348015610bb957600080fd5b50610504610bc83660046139bb565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b348015610bff57600080fd5b50610422610c0e3660046137d4565b611b48565b348015610c1f57600080fd5b50610422610c2e3660046137b7565b611bcd565b348015610c3f57600080fd5b50610504611c28565b348015610c5457600080fd5b50610422611c8e565b348015610c6957600080fd5b50610504601d5481565b348015610c7f57600080fd5b50610422610c8e3660046137b7565b611dfb565b348015610c9f57600080fd5b50610422610cae3660046137b7565b611e56565b348015610cbf57600080fd5b50610422610cce3660046137b7565b611e9a565b348015610cdf57600080fd5b5061050460285481565b348015610cf557600080fd5b5061049b610d043660046137b7565b611f93565b6060600f8054610d18906139f4565b80601f0160208091040260200160405190810160405280929190818152602001828054610d44906139f4565b8015610d915780601f10610d6657610100808354040283529160200191610d91565b820191906000526020600020905b815481529060010190602001808311610d7457829003601f168201915b5050505050905090565b6000610da8338484611fbc565b5060015b92915050565b33610dc56000546001600160a01b031690565b6001600160a01b031614610df45760405162461bcd60e51b8152600401610deb90613a28565b60405180910390fd5b6027805460ff1916911515919091179055565b610e136009600a613b57565b610e2090620186a0613b66565b81565b6000610e308484846120af565b6001600160a01b038416600090815260026020908152604080832033845290915290205482811015610e9b5760405162461bcd60e51b81526020600482015260146024820152735472616e73666572203e20616c6c6f77616e636560601b6044820152606401610deb565b610eaf8533610eaa8685613b85565b611fbc565b506001949350505050565b6000610ec582611514565b15610ee657506001600160a01b031660009081526022602052604090205490565b6001600160a01b038216600090815260226020526040902054610f088361230c565b610dac9190613b9c565b33610f256000546001600160a01b031690565b6001600160a01b031614610f4b5760405162461bcd60e51b8152600401610deb90613a28565b610f56600d82612392565b5050565b3360008181526002602090815260408083206001600160a01b03871684529091528120549091610da8918590610eaa908690613b9c565b33610fa46000546001600160a01b031690565b6001600160a01b031614610fca5760405162461bcd60e51b8152600401610deb90613a28565b602054811115610fd957600080fd5b8060206000828254610feb9190613b85565b90915550506014546001600160a01b03166108fc606461100c846032613b66565b6110169190613bb4565b6040518115909202916000818181858888f1935050505015801561103e573d6000803e3d6000fd5b506015546001600160a01b03166108fc606461105b846032613b66565b6110659190613bb4565b6040518115909202916000818181858888f19350505050158015610f56573d6000803e3d6000fd5b336110a06000546001600160a01b031690565b6001600160a01b0316146110c65760405162461bcd60e51b8152600401610deb90613a28565b6110ce6123a7565b565b336110e36000546001600160a01b031690565b6001600160a01b0316146111095760405162461bcd60e51b8152600401610deb90613a28565b602b80546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b336111466000546001600160a01b031690565b6001600160a01b03161461116c5760405162461bcd60e51b8152600401610deb90613a28565b6000846111798789613bd6565b6111839190613bd6565b90508060ff166064146111e75760405162461bcd60e51b815260206004820152602660248201527f6275726e2b6c69712b6d61726b6574696e67206e6565647320746f20657175616044820152656c203130302560d01b6064820152608401610deb565b50601a805460ff928316620100000262ff0000199484166101000261ffff19978516600160281b029790971665ff000000ffff199885166401000000000264ff00000000199a86166301000000029a909a1664ffff00000019909316929092179890981796909616959095179216919091179190911716919091179055565b336112796000546001600160a01b031690565b6001600160a01b03161461129f5760405162461bcd60e51b8152600401610deb90613a28565b6112b16112ac4283613b9c565b6124e7565b50565b336112c76000546001600160a01b031690565b6001600160a01b0316146112ed5760405162461bcd60e51b8152600401610deb90613a28565b6020805460009091556014546001600160a01b03166108fc606461100c846032613b66565b336113256000546001600160a01b031690565b6001600160a01b03161461134b5760405162461bcd60e51b8152600401610deb90613a28565b602c544210156113905760405162461bcd60e51b815260206004820152601060248201526f139bdd081e595d081d5b9b1bd8dad95960821b6044820152606401610deb565b61139c61070842613b9c565b602c556014546040516000916001600160a01b03169047908381818185875af1925050503d80600081146113ec576040519150601f19603f3d011682016040523d82523d6000602084013e6113f1565b606091505b50509050806112b157600080fd5b336114126000546001600160a01b031690565b6001600160a01b0316146114385760405162461bcd60e51b8152600401610deb90613a28565b6114446009600a613b57565b61144e9082613b66565b60195550565b6000806114636009600a613b57565b6017546114709190613bb4565b61147c6009600a613b57565b6018546114899190613bb4565b915091509091565b336114a46000546001600160a01b031690565b6001600160a01b0316146114ca5760405162461bcd60e51b8152600401610deb90613a28565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000610dac600b836124fa565b336115346000546001600160a01b031690565b6001600160a01b03161461155a5760405162461bcd60e51b8152600401610deb90613a28565b60648160ff16111561156b57600080fd5b601f805460ff191660ff92909216919091179055565b336115946000546001600160a01b031690565b6001600160a01b0316146115ba5760405162461bcd60e51b8152600401610deb90613a28565b602b805461ff00191661010017905542601155565b905090565b336115e76000546001600160a01b031690565b6001600160a01b03161461160d5760405162461bcd60e51b8152600401610deb90613a28565b602b805460ff1916911515919091179055565b606060108054610d18906139f4565b336116426000546001600160a01b031690565b6001600160a01b0316146116685760405162461bcd60e51b8152600401610deb90613a28565b60646016546116779190613bb4565b811061168257600080fd5b61168e6009600a613b57565b6116989083613b66565b91506116a66009600a613b57565b6116b09082613b66565b90506000603260ff166016546116c69190613bb4565b90506000603261ffff166016546116dd9190613bb4565b9050818410156117435760405162461bcd60e51b815260206004820152602b60248201527f6e657742616c616e63654c696d6974206e6565647320746f206265206174206c60448201526a19585cdd081d185c99d95d60aa1b6064820152608401610deb565b808310156117a45760405162461bcd60e51b815260206004820152602860248201527f6e657753656c6c4c696d6974206e6565647320746f206265206174206c6561736044820152671d081d185c99d95d60c21b6064820152608401610deb565b5050601791909155601855565b3360009081526002602090815260408083206001600160a01b0386168452909152812054828110156118145760405162461bcd60e51b815260206004820152600c60248201526b3c3020616c6c6f77616e636560a01b6044820152606401610deb565b6118233385610eaa8685613b85565b5060019392505050565b6000610da83384846120af565b60108054611847906139f4565b80601f0160208091040260200160405190810160405280929190818152602001828054611873906139f4565b80156118c05780601f10611895576101008083540402835291602001916118c0565b820191906000526020600020905b8154815290600101906020018083116118a357829003601f168201915b505050505081565b336118db6000546001600160a01b031690565b6001600160a01b0316146119015760405162461bcd60e51b8152600401610deb90613a28565b601580546001600160a01b0319166001600160a01b0392909216919091179055565b336119366000546001600160a01b031690565b6001600160a01b03161461195c5760405162461bcd60e51b8152600401610deb90613a28565b6029805460ff1916911515919091179055565b6110ce3361251c565b6000602c544210156119925742602c546115cf9190613b85565b50600090565b60006119a66009600a613b57565b6016546119b56009600a613b57565b6119c290620186a0613b66565b6119cc9190613b85565b6115cf9190613bb4565b336119e96000546001600160a01b031690565b6001600160a01b031614611a0f5760405162461bcd60e51b8152600401610deb90613a28565b610f56600582611fa0565b33611a2d6000546001600160a01b031690565b6001600160a01b031614611a535760405162461bcd60e51b8152600401610deb90613a28565b600f611a5f8382613c41565b506010611a6c8282613c41565b505050565b33611a846000546001600160a01b031690565b6001600160a01b031614611aaa5760405162461bcd60e51b8152600401610deb90613a28565b602655565b600f8054611847906139f4565b33611acf6000546001600160a01b031690565b6001600160a01b031614611af55760405162461bcd60e51b8152600401610deb90613a28565b8015611b435760405162461bcd60e51b815260206004820152601760248201527f53656c6c204c6f636b2074696d6520746f6f20686967680000000000000000006044820152606401610deb565b602855565b33611b5b6000546001600160a01b031690565b6001600160a01b031614611b815760405162461bcd60e51b8152600401610deb90613a28565b8015611bc85760405162461bcd60e51b8152602060048201526016602482015275084eaf24098dec6d640e8d2daca40e8dede40d0d2ced60531b6044820152606401610deb565b602a55565b33611be06000546001600160a01b031690565b6001600160a01b031614611c065760405162461bcd60e51b8152600401610deb90613a28565b601480546001600160a01b0319166001600160a01b0392909216919091179055565b601654600090815b611c3a600b6127cd565b811015611c885760016000611c50600b846127d7565b6001600160a01b03168152602081019190915260400160002054611c749083613b85565b915080611c8081613d01565b915050611c30565b50919050565b33611ca16000546001600160a01b031690565b6001600160a01b031614611cc75760405162461bcd60e51b8152600401610deb90613a28565b602c54421015611d0c5760405162461bcd60e51b815260206004820152601060248201526f139bdd081e595d081d5b9b1bd8dad95960821b6044820152606401610deb565b602b546040516370a0823160e01b8152306004820152620100009091046001600160a01b03169060009082906370a0823190602401602060405180830381865afa158015611d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d829190613d1a565b60145460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810183905291925083169063a9059cbb906044016020604051808303816000875af1158015611dd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6c9190613d33565b33611e0e6000546001600160a01b031690565b6001600160a01b031614611e345760405162461bcd60e51b8152600401610deb90613a28565b602380546001600160a01b0319166001600160a01b0392909216919091179055565b33611e696000546001600160a01b031690565b6001600160a01b031614611e8f5760405162461bcd60e51b8152600401610deb90613a28565b610f56600d82611fa0565b33611ead6000546001600160a01b031690565b6001600160a01b031614611ed35760405162461bcd60e51b8152600401610deb90613a28565b6001600160a01b038116611f385760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610deb565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000610dac600d836124fa565b6000611fb5836001600160a01b0384166127e3565b9392505050565b6001600160a01b0383166120065760405162461bcd60e51b8152602060048201526011602482015270417070726f76652066726f6d207a65726f60781b6044820152606401610deb565b6001600160a01b03821661204e5760405162461bcd60e51b815260206004820152600f60248201526e417070726f766520746f207a65726f60881b6044820152606401610deb565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166120fa5760405162461bcd60e51b81526020600482015260126024820152715472616e736665722066726f6d207a65726f60701b6044820152606401610deb565b6001600160a01b0382166121435760405162461bcd60e51b815260206004820152601060248201526f5472616e7366657220746f207a65726f60801b6044820152606401610deb565b60006121506005856124fa565b8061216157506121616005846124fa565b905060006001600160a01b03851630148061218457506001600160a01b03841630145b601b54601a549192506001600160a01b0390811691600091888116600160301b909204161480156121c65750816001600160a01b0316866001600160a01b0316145b806122015750601a546001600160a01b03878116600160301b909204161480156122015750816001600160a01b0316876001600160a01b0316145b601a549091506000906001600160a01b03898116600160301b90920416148061223b5750826001600160a01b0316886001600160a01b0316145b601a549091506000906001600160a01b03898116600160301b9092041614806122755750836001600160a01b0316886001600160a01b0316145b905084806122805750825b806122885750855b1561229d57612298898989612832565b612301565b602b54610100900460ff166122f45760405162461bcd60e51b815260206004820152601760248201527f74726164696e67206e6f742079657420656e61626c65640000000000000000006044820152606401610deb565b61230189898985856128fd565b505050505050505050565b6001600160a01b038116600090815260016020526040812054601c54829161233391613b66565b6001600160a01b03841660009081526021602052604090205490915081101561235f5750600092915050565b6001600160a01b038316600090815260216020526040902054600160401b906123889083613b85565b611fb59190613bb4565b6000611fb5836001600160a01b038416613095565b6025805460ff191660019081179091553060009081526020919091526040812054601a549091906123ed90600160281b810460ff90811691640100000000900416613bd6565b60ff1690506000602654905080831080612409575061ffff8216155b15612416575050506124db565b601a5460009061ffff84169061243790640100000000900460ff1684613b66565b6124419190613bb4565b9050600061244f8284613b85565b9050600061245e600284613bb4565b9050600061246c8285613b85565b9050600061247a8483613b9c565b90504761248682613182565b60006124928247613b85565b90506000836124a18684613b66565b6124ab9190613bb4565b90506124b786826132db565b60006124c38447613b85565b90506124ce816133a3565b5050505050505050505050505b6025805460ff19169055565b602c5481116124f557600080fd5b602c55565b6001600160a01b03811660009081526001830160205260408120541515611fb5565b601b54600160a01b900460ff161561253357600080fd5b601b805460ff60a01b1916600160a01b179055600061255182611514565b1561257957506001600160a01b038116600090815260226020526040812080549190556125f9565b60006125848361230c565b6001600160a01b038416600090815260016020526040902054601c549192506125ac91613b66565b6001600160a01b0384166000908152602160209081526040808320939093556022905220546125dc908290613b9c565b6001600160a01b0384166000908152602260205260408120559150505b80600003612612575050601b805460ff60a01b19169055565b80601e60008282546126249190613b9c565b90915550506040805160028082526060820183526000926020830190803683375050601b54604080516302768aa360e51b815290519394506001600160a01b0390911692634ed15460925060048083019260209291908290030181865afa158015612693573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b79190613d50565b816000815181106126ca576126ca613d6d565b6001600160a01b0392831660209182029290920101526023548251911690829060019081106126fb576126fb613d6d565b6001600160a01b039283166020918202929092010152601b5460405163118d44ef60e21b815291169063463513bc90849061274190600090869089904290600401613dc7565b6000604051808303818588803b15801561275a57600080fd5b505af115801561276e573d6000803e3d6000fd5b5050604080518681526001600160a01b03881660208201527f317914d20ce527c740e1a0313da7590c7b7f67f36a6ee556d71ddaacad948a9e94500191506127b39050565b60405180910390a15050601b805460ff60a01b1916905550565b6000610dac825490565b6000611fb5838361346f565b600081815260018301602052604081205461282a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610dac565b506000610dac565b6001600160a01b038316600090815260016020526040902054818110156128965760405162461bcd60e51b81526020600482015260186024820152775472616e7366657220657863656564732062616c616e636560401b6044820152606401610deb565b6128a084836134f5565b6128aa83836135b6565b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516128ef91815260200190565b60405180910390a350505050565b6001600160a01b038085166000908152600160205260408082205492881682529020548481101561296b5760405162461bcd60e51b81526020600482015260186024820152775472616e7366657220657863656564732062616c616e636560401b6044820152606401610deb565b60008315612b1e5761297e6007896124fa565b612a13576001600160a01b038816600090815260036020526040902054421015806129ab575060275460ff165b6129ec5760405162461bcd60e51b815260206004820152601260248201527153656c6c657220696e2073656c6c4c6f636b60701b6044820152606401610deb565b6028546129f99042613b9c565b6001600160a01b0389166000908152600360205260409020555b601854861115612a575760405162461bcd60e51b815260206004820152600f60248201526e223ab6b810383937ba32b1ba34b7b760891b6044820152606401610deb565b612a62600d896124fa565b15612aa65760405162461bcd60e51b81526020600482015260146024820152734164647265737320626c61636b6c69737465642160601b6044820152606401610deb565b601254601154612ab69190613b9c565b4211158015612ac757506013546001145b15612b0d57612ad7600d89611fa0565b506040516001600160a01b038916907f8c21268f4379683ad2b81c32b4357f44a17e83e73d741ba6e8c23e085e57135190600090a25b50601a54610100900460ff16612f32565b8415612d2f57612b2f6009886124fa565b612bc2576001600160a01b03871660009081526004602052604090205442101580612b5c575060295460ff165b612b9b5760405162461bcd60e51b815260206004820152601060248201526f427579657220696e206275794c6f636b60801b6044820152606401610deb565b602a54612ba89042613b9c565b6001600160a01b0388166000908152600460205260409020555b601754612bcf8785613b9c565b1115612c105760405162461bcd60e51b815260206004820152601060248201526f3bb430b63290383937ba32b1ba34b7b760811b6044820152606401610deb565b601954861115612c6d5760405162461bcd60e51b815260206004820152602260248201527f547820616d6f756e7420657863656564696e67206d61782062757920616d6f756044820152611b9d60f21b6064820152608401610deb565b612c78600d886124fa565b15612cbc5760405162461bcd60e51b81526020600482015260146024820152734164647265737320626c61636b6c69737465642160601b6044820152606401610deb565b601254601154612ccc9190613b9c565b4211158015612cdd57506013546001145b15612d2357612ced600d88611fa0565b506040516001600160a01b038816907f8c21268f4379683ad2b81c32b4357f44a17e83e73d741ba6e8c23e085e57135190600090a25b50601a5460ff16612f32565b612d3b6009600a613b57565b8611612d4a57612d4a8861251c565b601754612d578785613b9c565b1115612d985760405162461bcd60e51b815260206004820152601060248201526f3bb430b63290383937ba32b1ba34b7b760811b6044820152606401610deb565b612da36007896124fa565b612e0d576001600160a01b03881660009081526003602052604090205442101580612dd0575060275460ff165b612e0d5760405162461bcd60e51b815260206004820152600e60248201526d53656e64657220696e204c6f636b60901b6044820152606401610deb565b612e18600d896124fa565b15612e655760405162461bcd60e51b815260206004820152601b60248201527f53656e646572206164647265737320626c61636b6c69737465642100000000006044820152606401610deb565b612e70600d886124fa565b15612ebd5760405162461bcd60e51b815260206004820152601e60248201527f526563697069656e74206164647265737320626c61636b6c69737465642100006044820152606401610deb565b601254601154612ecd9190613b9c565b4211158015612ede57506013546001145b15612f2457612eee600d89611fa0565b506040516001600160a01b038916907f8c21268f4379683ad2b81c32b4357f44a17e83e73d741ba6e8c23e085e57135190600090a25b50601a5462010000900460ff165b601a546001600160a01b03898116600160301b9092041614801590612f5a5750602b5460ff16155b8015612f69575060255460ff16155b8015612f725750835b15612f7f57612f7f6123a7565b6000612f9b8783601a60039054906101000a900460ff16613681565b601a54909150600090612fcf9089908590612fca9060ff6401000000008204811691600160281b900416613bd6565b613681565b90506000612fdd8284613b9c565b612fe7908a613b85565b9050612ff38b8a6134f5565b3060009081526001602052604081208054849290613012908490613b9c565b92505081905550826016600082825461302b9190613b85565b9091555061303b90508a826135b6565b896001600160a01b03168b6001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161308091815260200190565b60405180910390a35050505050505050505050565b600081815260018301602052604081205480156131785760006130b9600183613b85565b85549091506000906130cd90600190613b85565b905060008660000182815481106130e6576130e6613d6d565b906000526020600020015490508087600001848154811061310957613109613d6d565b60009182526020808320909101929092558281526001890190915260409020849055865487908061313c5761313c613dfc565b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610dac565b6000915050610dac565b601b5461319a9030906001600160a01b031683611fbc565b60408051600280825260608201835260009260208301908036833701905050905030816000815181106131cf576131cf613d6d565b6001600160a01b03928316602091820292909201810191909152601b54604080516302768aa360e51b815290519190931692634ed154609260048083019391928290030181865afa158015613228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061324c9190613d50565b8160018151811061325f5761325f613d6d565b6001600160a01b039283166020918202929092010152601b5460405163b43d9bbb60e01b815291169063b43d9bbb906132a5908590600090869030904290600401613e12565b600060405180830381600087803b1580156132bf57600080fd5b505af11580156132d3573d6000803e3d6000fd5b505050505050565b80602460008282546132ed9190613b9c565b9091555050601b5461330a9030906001600160a01b031684611fbc565b601b54604051633994a6ad60e21b8152306004820181905260248201859052600060448301819052606483015260848201524260a48201526001600160a01b039091169063e6529ab490839060c40160606040518083038185885af1158015613377573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061339c9190613e4e565b5050505050565b601f546000906064906133b99060ff1684613b66565b6133c39190613bb4565b905060006133d18284613b85565b905081602060008282546133e59190613b9c565b90915550508015611a6c5780601d60008282546134029190613b9c565b9091555060009050613412611c28565b90508060000361343957816020600082825461342e9190613b9c565b909155506134699050565b80613448600160401b84613b66565b6134529190613bb4565b601c60008282546134639190613b9c565b90915550505b50505050565b815460009082106134cd5760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610deb565b8260000182815481106134e2576134e2613d6d565b9060005260206000200154905092915050565b6001600160a01b038216600090815260016020526040812054613519908390613b85565b905061352483611514565b15613549576001600160a01b0390921660009081526001602052604090209190915550565b60006135548461230c565b6001600160a01b0385166000908152600160205260409020839055601c54909150613580908390613b66565b6001600160a01b038516600090815260216020908152604080832093909355602290529081208054839290613463908490613b9c565b6001600160a01b0382166000908152600160205260408120546135da908390613b9c565b90506135e583611514565b1561360a576001600160a01b0390921660009081526001602052604090209190915550565b60006136158461230c565b905081601c546136259190613b66565b6001600160a01b03851660009081526021602090815260408083209390935560229052908120805483929061365b908490613b9c565b9091555050506001600160a01b0390921660009081526001602052604090209190915550565b60006127108260ff168460ff16866136999190613b66565b6136a39190613b66565b6136ad9190613bb4565b949350505050565b600060208083528351808285015260005b818110156136e2578581018301518582016040015282016136c6565b818111156136f4576000604083870101525b50601f01601f1916929092016040019392505050565b6001600160a01b03811681146112b157600080fd5b6000806040838503121561373257600080fd5b823561373d8161370a565b946020939093013593505050565b80151581146112b157600080fd5b60006020828403121561376b57600080fd5b8135611fb58161374b565b60008060006060848603121561378b57600080fd5b83356137968161370a565b925060208401356137a68161370a565b929592945050506040919091013590565b6000602082840312156137c957600080fd5b8135611fb58161370a565b6000602082840312156137e657600080fd5b5035919050565b803560ff811681146137fe57600080fd5b919050565b60008060008060008060c0878903121561381c57600080fd5b613825876137ed565b9550613833602088016137ed565b9450613841604088016137ed565b935061384f606088016137ed565b925061385d608088016137ed565b915061386b60a088016137ed565b90509295509295509295565b60006020828403121561388957600080fd5b611fb5826137ed565b600080604083850312156138a557600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126138db57600080fd5b813567ffffffffffffffff808211156138f6576138f66138b4565b604051601f8301601f19908116603f0116810190828211818310171561391e5761391e6138b4565b8160405283815286602085880101111561393757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561396a57600080fd5b823567ffffffffffffffff8082111561398257600080fd5b61398e868387016138ca565b935060208501359150808211156139a457600080fd5b506139b1858286016138ca565b9150509250929050565b600080604083850312156139ce57600080fd5b82356139d98161370a565b915060208301356139e98161370a565b809150509250929050565b600181811c90821680613a0857607f821691505b602082108103611c8857634e487b7160e01b600052602260045260246000fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600181815b80851115613aae578160001904821115613a9457613a94613a5d565b80851615613aa157918102915b93841c9390800290613a78565b509250929050565b600082613ac557506001610dac565b81613ad257506000610dac565b8160018114613ae85760028114613af257613b0e565b6001915050610dac565b60ff841115613b0357613b03613a5d565b50506001821b610dac565b5060208310610133831016604e8410600b8410161715613b31575081810a610dac565b613b3b8383613a73565b8060001904821115613b4f57613b4f613a5d565b029392505050565b6000611fb560ff841683613ab6565b6000816000190483118215151615613b8057613b80613a5d565b500290565b600082821015613b9757613b97613a5d565b500390565b60008219821115613baf57613baf613a5d565b500190565b600082613bd157634e487b7160e01b600052601260045260246000fd5b500490565b600060ff821660ff84168060ff03821115613bf357613bf3613a5d565b019392505050565b601f821115611a6c57600081815260208120601f850160051c81016020861015613c225750805b601f850160051c820191505b818110156132d357828155600101613c2e565b815167ffffffffffffffff811115613c5b57613c5b6138b4565b613c6f81613c6984546139f4565b84613bfb565b602080601f831160018114613ca45760008415613c8c5750858301515b600019600386901b1c1916600185901b1785556132d3565b600085815260208120601f198616915b82811015613cd357888601518255948401946001909101908401613cb4565b5085821015613cf15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060018201613d1357613d13613a5d565b5060010190565b600060208284031215613d2c57600080fd5b5051919050565b600060208284031215613d4557600080fd5b8151611fb58161374b565b600060208284031215613d6257600080fd5b8151611fb58161370a565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015613dbc5781516001600160a01b031687529582019590820190600101613d97565b509495945050505050565b848152608060208201526000613de06080830186613d83565b6001600160a01b03949094166040830152506060015292915050565b634e487b7160e01b600052603160045260246000fd5b85815284602082015260a060408201526000613e3160a0830186613d83565b6001600160a01b0394909416606083015250608001529392505050565b600080600060608486031215613e6357600080fd5b835192506020840151915060408401519050925092509256fea2646970667358221220f788e1992290c2c8d75f07668172ff9e3ce6846f2b1d951835fced6bf338553364736f6c634300080f0033

Deployed ByteCode

0x60806040526004361061041b5760003560e01c806373ddf08e1161021c578063c3a3c03211610122578063e2fd002a116100b0578063f0cc761211610077578063f0cc761214610c73578063f2c816ae14610c93578063f2fde38b14610cb3578063f88b0e4614610cd3578063fe575a8714610ce957005b8063e2fd002a14610bf3578063e68f136a14610c13578063e69e03ee14610c33578063ef12a33014610c48578063f00df36514610c5d57005b8063d11edf74116100f4578063d11edf7414610b38578063d28d885214610b58578063d51f383b14610b6d578063db886f2314610b8d578063dd62ed3e14610bad57005b8063c3a3c03214610ace578063c3f4f54f14610ae3578063cd979a7e14610af8578063d0291d6614610b1857005b8063951ed3fb116101aa578063b09f126611610171578063b09f126614610a44578063b58a56cd14610a59578063b766a38614610a79578063c054f2f414610a99578063c280895414610ab957005b8063951ed3fb146109af57806395d89b41146109cf5780639fa62d5f146109e4578063a457c2d714610a04578063a9059cbb14610a2457005b806386d0ada8116101ee57806386d0ada81461090b578063887c60fb14610925578063893d20e81461093f5780638da5cb5b1461097157806394e8075d1461098f57005b806373ddf08e146108aa578063762bb282146108ca5780637b9e987a146108e05780638650e92a146108f557005b80634089b170116103215780635b80f625116102af5780636ea4caab116102765780636ea4caab146107f55780636f89e4091461081557806370a082311461083f578063715018a6146108755780637335307b1461088a57005b80635b80f625146107965780635c69f69014610629578063643daaea146107ab57806368ba3d7a146107cb5780636a6bc5ad146107e057005b80634cdaf0ae116102f35780634cdaf0ae146107145780634f91e48c1461073457806357ad67d11461074a57806357b1c4f21461076a57806358e553651461078057005b80634089b170146106b457806344f3c83a146106ca578063459a7484146106e05780634ada218b146106f557005b80632973ef2d116103a95780633478154b116103705780633478154b1461062957806335e82f3a1461063e578063395093511461065e5780633d2bdb1d1461067e5780633da56f181461069e57005b80632973ef2d1461055d5780633054f8a3146105c6578063311a8697146105e0578063313ce567146105f557806332ac487f1461060957005b806314e91377116103ed57806314e91377146104d357806318160ddd146104f35780631eb25d131461051257806323b872dd14610527578063269a6aae1461054757005b806306fdde031461042457806309218ee71461044f578063095ea7b31461047b5780630fd99e16146104ab57005b3661042257005b005b34801561043057600080fd5b50610439610d09565b60405161044691906136b5565b60405180910390f35b34801561045b57600080fd5b50601f546104699060ff1681565b60405160ff9091168152602001610446565b34801561048757600080fd5b5061049b61049636600461371f565b610d9b565b6040519015158152602001610446565b3480156104b757600080fd5b506104c0603281565b60405161ffff9091168152602001610446565b3480156104df57600080fd5b506104226104ee366004613759565b610db2565b3480156104ff57600080fd5b506016545b604051908152602001610446565b34801561051e57600080fd5b50610504610e07565b34801561053357600080fd5b5061049b610542366004613776565b610e23565b34801561055357600080fd5b5061050460125481565b34801561056957600080fd5b50601a546040805160ff6301000000840481168252640100000000840481166020830152600160281b84048116928201929092528183166060820152610100830482166080820152620100009092041660a082015260c001610446565b3480156105d257600080fd5b5060295461049b9060ff1681565b3480156105ec57600080fd5b50610469603281565b34801561060157600080fd5b506009610469565b34801561061557600080fd5b506105046106243660046137b7565b610eba565b34801561063557600080fd5b506104c0600081565b34801561064a57600080fd5b506104226106593660046137b7565b610f12565b34801561066a57600080fd5b5061049b61067936600461371f565b610f5a565b34801561068a57600080fd5b506104226106993660046137d4565b610f91565b3480156106aa57600080fd5b5061050460135481565b3480156106c057600080fd5b50610504601e5481565b3480156106d657600080fd5b50610504602a5481565b3480156106ec57600080fd5b5061042261108d565b34801561070157600080fd5b50602b5461049b90610100900460ff1681565b34801561072057600080fd5b5061042261072f3660046137b7565b6110d0565b34801561074057600080fd5b5061050460185481565b34801561075657600080fd5b50610422610765366004613803565b611133565b34801561077657600080fd5b5061050460245481565b34801561078c57600080fd5b5061050460205481565b3480156107a257600080fd5b50602654610504565b3480156107b757600080fd5b506104226107c63660046137d4565b611266565b3480156107d757600080fd5b506104226112b4565b3480156107ec57600080fd5b50610422611312565b34801561080157600080fd5b506104226108103660046137d4565b6113ff565b34801561082157600080fd5b5061082a611454565b60408051928352602083019190915201610446565b34801561084b57600080fd5b5061050461085a3660046137b7565b6001600160a01b031660009081526001602052604090205490565b34801561088157600080fd5b50610422611491565b34801561089657600080fd5b5061049b6108a53660046137b7565b611514565b3480156108b657600080fd5b506104226108c5366004613877565b611521565b3480156108d657600080fd5b5061050460175481565b3480156108ec57600080fd5b50610422611581565b34801561090157600080fd5b50610504601c5481565b34801561091757600080fd5b50602b5461049b9060ff1681565b34801561093157600080fd5b5060275461049b9060ff1681565b34801561094b57600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610446565b34801561097d57600080fd5b506000546001600160a01b0316610959565b34801561099b57600080fd5b50601454610959906001600160a01b031681565b3480156109bb57600080fd5b506104226109ca366004613759565b6115d4565b3480156109db57600080fd5b50610439611620565b3480156109f057600080fd5b506104226109ff366004613892565b61162f565b348015610a1057600080fd5b5061049b610a1f36600461371f565b6117b1565b348015610a3057600080fd5b5061049b610a3f36600461371f565b61182d565b348015610a5057600080fd5b5061043961183a565b348015610a6557600080fd5b50610422610a743660046137b7565b6118c8565b348015610a8557600080fd5b50610422610a94366004613759565b611923565b348015610aa557600080fd5b50602354610959906001600160a01b031681565b348015610ac557600080fd5b5061042261196f565b348015610ada57600080fd5b50610504611978565b348015610aef57600080fd5b50610504611998565b348015610b0457600080fd5b50610422610b133660046137b7565b6119d6565b348015610b2457600080fd5b50610422610b33366004613957565b611a1a565b348015610b4457600080fd5b50610422610b533660046137d4565b611a71565b348015610b6457600080fd5b50610439611aaf565b348015610b7957600080fd5b50610422610b883660046137d4565b611abc565b348015610b9957600080fd5b50601554610959906001600160a01b031681565b348015610bb957600080fd5b50610504610bc83660046139bb565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b348015610bff57600080fd5b50610422610c0e3660046137d4565b611b48565b348015610c1f57600080fd5b50610422610c2e3660046137b7565b611bcd565b348015610c3f57600080fd5b50610504611c28565b348015610c5457600080fd5b50610422611c8e565b348015610c6957600080fd5b50610504601d5481565b348015610c7f57600080fd5b50610422610c8e3660046137b7565b611dfb565b348015610c9f57600080fd5b50610422610cae3660046137b7565b611e56565b348015610cbf57600080fd5b50610422610cce3660046137b7565b611e9a565b348015610cdf57600080fd5b5061050460285481565b348015610cf557600080fd5b5061049b610d043660046137b7565b611f93565b6060600f8054610d18906139f4565b80601f0160208091040260200160405190810160405280929190818152602001828054610d44906139f4565b8015610d915780601f10610d6657610100808354040283529160200191610d91565b820191906000526020600020905b815481529060010190602001808311610d7457829003601f168201915b5050505050905090565b6000610da8338484611fbc565b5060015b92915050565b33610dc56000546001600160a01b031690565b6001600160a01b031614610df45760405162461bcd60e51b8152600401610deb90613a28565b60405180910390fd5b6027805460ff1916911515919091179055565b610e136009600a613b57565b610e2090620186a0613b66565b81565b6000610e308484846120af565b6001600160a01b038416600090815260026020908152604080832033845290915290205482811015610e9b5760405162461bcd60e51b81526020600482015260146024820152735472616e73666572203e20616c6c6f77616e636560601b6044820152606401610deb565b610eaf8533610eaa8685613b85565b611fbc565b506001949350505050565b6000610ec582611514565b15610ee657506001600160a01b031660009081526022602052604090205490565b6001600160a01b038216600090815260226020526040902054610f088361230c565b610dac9190613b9c565b33610f256000546001600160a01b031690565b6001600160a01b031614610f4b5760405162461bcd60e51b8152600401610deb90613a28565b610f56600d82612392565b5050565b3360008181526002602090815260408083206001600160a01b03871684529091528120549091610da8918590610eaa908690613b9c565b33610fa46000546001600160a01b031690565b6001600160a01b031614610fca5760405162461bcd60e51b8152600401610deb90613a28565b602054811115610fd957600080fd5b8060206000828254610feb9190613b85565b90915550506014546001600160a01b03166108fc606461100c846032613b66565b6110169190613bb4565b6040518115909202916000818181858888f1935050505015801561103e573d6000803e3d6000fd5b506015546001600160a01b03166108fc606461105b846032613b66565b6110659190613bb4565b6040518115909202916000818181858888f19350505050158015610f56573d6000803e3d6000fd5b336110a06000546001600160a01b031690565b6001600160a01b0316146110c65760405162461bcd60e51b8152600401610deb90613a28565b6110ce6123a7565b565b336110e36000546001600160a01b031690565b6001600160a01b0316146111095760405162461bcd60e51b8152600401610deb90613a28565b602b80546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b336111466000546001600160a01b031690565b6001600160a01b03161461116c5760405162461bcd60e51b8152600401610deb90613a28565b6000846111798789613bd6565b6111839190613bd6565b90508060ff166064146111e75760405162461bcd60e51b815260206004820152602660248201527f6275726e2b6c69712b6d61726b6574696e67206e6565647320746f20657175616044820152656c203130302560d01b6064820152608401610deb565b50601a805460ff928316620100000262ff0000199484166101000261ffff19978516600160281b029790971665ff000000ffff199885166401000000000264ff00000000199a86166301000000029a909a1664ffff00000019909316929092179890981796909616959095179216919091179190911716919091179055565b336112796000546001600160a01b031690565b6001600160a01b03161461129f5760405162461bcd60e51b8152600401610deb90613a28565b6112b16112ac4283613b9c565b6124e7565b50565b336112c76000546001600160a01b031690565b6001600160a01b0316146112ed5760405162461bcd60e51b8152600401610deb90613a28565b6020805460009091556014546001600160a01b03166108fc606461100c846032613b66565b336113256000546001600160a01b031690565b6001600160a01b03161461134b5760405162461bcd60e51b8152600401610deb90613a28565b602c544210156113905760405162461bcd60e51b815260206004820152601060248201526f139bdd081e595d081d5b9b1bd8dad95960821b6044820152606401610deb565b61139c61070842613b9c565b602c556014546040516000916001600160a01b03169047908381818185875af1925050503d80600081146113ec576040519150601f19603f3d011682016040523d82523d6000602084013e6113f1565b606091505b50509050806112b157600080fd5b336114126000546001600160a01b031690565b6001600160a01b0316146114385760405162461bcd60e51b8152600401610deb90613a28565b6114446009600a613b57565b61144e9082613b66565b60195550565b6000806114636009600a613b57565b6017546114709190613bb4565b61147c6009600a613b57565b6018546114899190613bb4565b915091509091565b336114a46000546001600160a01b031690565b6001600160a01b0316146114ca5760405162461bcd60e51b8152600401610deb90613a28565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000610dac600b836124fa565b336115346000546001600160a01b031690565b6001600160a01b03161461155a5760405162461bcd60e51b8152600401610deb90613a28565b60648160ff16111561156b57600080fd5b601f805460ff191660ff92909216919091179055565b336115946000546001600160a01b031690565b6001600160a01b0316146115ba5760405162461bcd60e51b8152600401610deb90613a28565b602b805461ff00191661010017905542601155565b905090565b336115e76000546001600160a01b031690565b6001600160a01b03161461160d5760405162461bcd60e51b8152600401610deb90613a28565b602b805460ff1916911515919091179055565b606060108054610d18906139f4565b336116426000546001600160a01b031690565b6001600160a01b0316146116685760405162461bcd60e51b8152600401610deb90613a28565b60646016546116779190613bb4565b811061168257600080fd5b61168e6009600a613b57565b6116989083613b66565b91506116a66009600a613b57565b6116b09082613b66565b90506000603260ff166016546116c69190613bb4565b90506000603261ffff166016546116dd9190613bb4565b9050818410156117435760405162461bcd60e51b815260206004820152602b60248201527f6e657742616c616e63654c696d6974206e6565647320746f206265206174206c60448201526a19585cdd081d185c99d95d60aa1b6064820152608401610deb565b808310156117a45760405162461bcd60e51b815260206004820152602860248201527f6e657753656c6c4c696d6974206e6565647320746f206265206174206c6561736044820152671d081d185c99d95d60c21b6064820152608401610deb565b5050601791909155601855565b3360009081526002602090815260408083206001600160a01b0386168452909152812054828110156118145760405162461bcd60e51b815260206004820152600c60248201526b3c3020616c6c6f77616e636560a01b6044820152606401610deb565b6118233385610eaa8685613b85565b5060019392505050565b6000610da83384846120af565b60108054611847906139f4565b80601f0160208091040260200160405190810160405280929190818152602001828054611873906139f4565b80156118c05780601f10611895576101008083540402835291602001916118c0565b820191906000526020600020905b8154815290600101906020018083116118a357829003601f168201915b505050505081565b336118db6000546001600160a01b031690565b6001600160a01b0316146119015760405162461bcd60e51b8152600401610deb90613a28565b601580546001600160a01b0319166001600160a01b0392909216919091179055565b336119366000546001600160a01b031690565b6001600160a01b03161461195c5760405162461bcd60e51b8152600401610deb90613a28565b6029805460ff1916911515919091179055565b6110ce3361251c565b6000602c544210156119925742602c546115cf9190613b85565b50600090565b60006119a66009600a613b57565b6016546119b56009600a613b57565b6119c290620186a0613b66565b6119cc9190613b85565b6115cf9190613bb4565b336119e96000546001600160a01b031690565b6001600160a01b031614611a0f5760405162461bcd60e51b8152600401610deb90613a28565b610f56600582611fa0565b33611a2d6000546001600160a01b031690565b6001600160a01b031614611a535760405162461bcd60e51b8152600401610deb90613a28565b600f611a5f8382613c41565b506010611a6c8282613c41565b505050565b33611a846000546001600160a01b031690565b6001600160a01b031614611aaa5760405162461bcd60e51b8152600401610deb90613a28565b602655565b600f8054611847906139f4565b33611acf6000546001600160a01b031690565b6001600160a01b031614611af55760405162461bcd60e51b8152600401610deb90613a28565b8015611b435760405162461bcd60e51b815260206004820152601760248201527f53656c6c204c6f636b2074696d6520746f6f20686967680000000000000000006044820152606401610deb565b602855565b33611b5b6000546001600160a01b031690565b6001600160a01b031614611b815760405162461bcd60e51b8152600401610deb90613a28565b8015611bc85760405162461bcd60e51b8152602060048201526016602482015275084eaf24098dec6d640e8d2daca40e8dede40d0d2ced60531b6044820152606401610deb565b602a55565b33611be06000546001600160a01b031690565b6001600160a01b031614611c065760405162461bcd60e51b8152600401610deb90613a28565b601480546001600160a01b0319166001600160a01b0392909216919091179055565b601654600090815b611c3a600b6127cd565b811015611c885760016000611c50600b846127d7565b6001600160a01b03168152602081019190915260400160002054611c749083613b85565b915080611c8081613d01565b915050611c30565b50919050565b33611ca16000546001600160a01b031690565b6001600160a01b031614611cc75760405162461bcd60e51b8152600401610deb90613a28565b602c54421015611d0c5760405162461bcd60e51b815260206004820152601060248201526f139bdd081e595d081d5b9b1bd8dad95960821b6044820152606401610deb565b602b546040516370a0823160e01b8152306004820152620100009091046001600160a01b03169060009082906370a0823190602401602060405180830381865afa158015611d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d829190613d1a565b60145460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810183905291925083169063a9059cbb906044016020604051808303816000875af1158015611dd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6c9190613d33565b33611e0e6000546001600160a01b031690565b6001600160a01b031614611e345760405162461bcd60e51b8152600401610deb90613a28565b602380546001600160a01b0319166001600160a01b0392909216919091179055565b33611e696000546001600160a01b031690565b6001600160a01b031614611e8f5760405162461bcd60e51b8152600401610deb90613a28565b610f56600d82611fa0565b33611ead6000546001600160a01b031690565b6001600160a01b031614611ed35760405162461bcd60e51b8152600401610deb90613a28565b6001600160a01b038116611f385760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610deb565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000610dac600d836124fa565b6000611fb5836001600160a01b0384166127e3565b9392505050565b6001600160a01b0383166120065760405162461bcd60e51b8152602060048201526011602482015270417070726f76652066726f6d207a65726f60781b6044820152606401610deb565b6001600160a01b03821661204e5760405162461bcd60e51b815260206004820152600f60248201526e417070726f766520746f207a65726f60881b6044820152606401610deb565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166120fa5760405162461bcd60e51b81526020600482015260126024820152715472616e736665722066726f6d207a65726f60701b6044820152606401610deb565b6001600160a01b0382166121435760405162461bcd60e51b815260206004820152601060248201526f5472616e7366657220746f207a65726f60801b6044820152606401610deb565b60006121506005856124fa565b8061216157506121616005846124fa565b905060006001600160a01b03851630148061218457506001600160a01b03841630145b601b54601a549192506001600160a01b0390811691600091888116600160301b909204161480156121c65750816001600160a01b0316866001600160a01b0316145b806122015750601a546001600160a01b03878116600160301b909204161480156122015750816001600160a01b0316876001600160a01b0316145b601a549091506000906001600160a01b03898116600160301b90920416148061223b5750826001600160a01b0316886001600160a01b0316145b601a549091506000906001600160a01b03898116600160301b9092041614806122755750836001600160a01b0316886001600160a01b0316145b905084806122805750825b806122885750855b1561229d57612298898989612832565b612301565b602b54610100900460ff166122f45760405162461bcd60e51b815260206004820152601760248201527f74726164696e67206e6f742079657420656e61626c65640000000000000000006044820152606401610deb565b61230189898985856128fd565b505050505050505050565b6001600160a01b038116600090815260016020526040812054601c54829161233391613b66565b6001600160a01b03841660009081526021602052604090205490915081101561235f5750600092915050565b6001600160a01b038316600090815260216020526040902054600160401b906123889083613b85565b611fb59190613bb4565b6000611fb5836001600160a01b038416613095565b6025805460ff191660019081179091553060009081526020919091526040812054601a549091906123ed90600160281b810460ff90811691640100000000900416613bd6565b60ff1690506000602654905080831080612409575061ffff8216155b15612416575050506124db565b601a5460009061ffff84169061243790640100000000900460ff1684613b66565b6124419190613bb4565b9050600061244f8284613b85565b9050600061245e600284613bb4565b9050600061246c8285613b85565b9050600061247a8483613b9c565b90504761248682613182565b60006124928247613b85565b90506000836124a18684613b66565b6124ab9190613bb4565b90506124b786826132db565b60006124c38447613b85565b90506124ce816133a3565b5050505050505050505050505b6025805460ff19169055565b602c5481116124f557600080fd5b602c55565b6001600160a01b03811660009081526001830160205260408120541515611fb5565b601b54600160a01b900460ff161561253357600080fd5b601b805460ff60a01b1916600160a01b179055600061255182611514565b1561257957506001600160a01b038116600090815260226020526040812080549190556125f9565b60006125848361230c565b6001600160a01b038416600090815260016020526040902054601c549192506125ac91613b66565b6001600160a01b0384166000908152602160209081526040808320939093556022905220546125dc908290613b9c565b6001600160a01b0384166000908152602260205260408120559150505b80600003612612575050601b805460ff60a01b19169055565b80601e60008282546126249190613b9c565b90915550506040805160028082526060820183526000926020830190803683375050601b54604080516302768aa360e51b815290519394506001600160a01b0390911692634ed15460925060048083019260209291908290030181865afa158015612693573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b79190613d50565b816000815181106126ca576126ca613d6d565b6001600160a01b0392831660209182029290920101526023548251911690829060019081106126fb576126fb613d6d565b6001600160a01b039283166020918202929092010152601b5460405163118d44ef60e21b815291169063463513bc90849061274190600090869089904290600401613dc7565b6000604051808303818588803b15801561275a57600080fd5b505af115801561276e573d6000803e3d6000fd5b5050604080518681526001600160a01b03881660208201527f317914d20ce527c740e1a0313da7590c7b7f67f36a6ee556d71ddaacad948a9e94500191506127b39050565b60405180910390a15050601b805460ff60a01b1916905550565b6000610dac825490565b6000611fb5838361346f565b600081815260018301602052604081205461282a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610dac565b506000610dac565b6001600160a01b038316600090815260016020526040902054818110156128965760405162461bcd60e51b81526020600482015260186024820152775472616e7366657220657863656564732062616c616e636560401b6044820152606401610deb565b6128a084836134f5565b6128aa83836135b6565b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516128ef91815260200190565b60405180910390a350505050565b6001600160a01b038085166000908152600160205260408082205492881682529020548481101561296b5760405162461bcd60e51b81526020600482015260186024820152775472616e7366657220657863656564732062616c616e636560401b6044820152606401610deb565b60008315612b1e5761297e6007896124fa565b612a13576001600160a01b038816600090815260036020526040902054421015806129ab575060275460ff165b6129ec5760405162461bcd60e51b815260206004820152601260248201527153656c6c657220696e2073656c6c4c6f636b60701b6044820152606401610deb565b6028546129f99042613b9c565b6001600160a01b0389166000908152600360205260409020555b601854861115612a575760405162461bcd60e51b815260206004820152600f60248201526e223ab6b810383937ba32b1ba34b7b760891b6044820152606401610deb565b612a62600d896124fa565b15612aa65760405162461bcd60e51b81526020600482015260146024820152734164647265737320626c61636b6c69737465642160601b6044820152606401610deb565b601254601154612ab69190613b9c565b4211158015612ac757506013546001145b15612b0d57612ad7600d89611fa0565b506040516001600160a01b038916907f8c21268f4379683ad2b81c32b4357f44a17e83e73d741ba6e8c23e085e57135190600090a25b50601a54610100900460ff16612f32565b8415612d2f57612b2f6009886124fa565b612bc2576001600160a01b03871660009081526004602052604090205442101580612b5c575060295460ff165b612b9b5760405162461bcd60e51b815260206004820152601060248201526f427579657220696e206275794c6f636b60801b6044820152606401610deb565b602a54612ba89042613b9c565b6001600160a01b0388166000908152600460205260409020555b601754612bcf8785613b9c565b1115612c105760405162461bcd60e51b815260206004820152601060248201526f3bb430b63290383937ba32b1ba34b7b760811b6044820152606401610deb565b601954861115612c6d5760405162461bcd60e51b815260206004820152602260248201527f547820616d6f756e7420657863656564696e67206d61782062757920616d6f756044820152611b9d60f21b6064820152608401610deb565b612c78600d886124fa565b15612cbc5760405162461bcd60e51b81526020600482015260146024820152734164647265737320626c61636b6c69737465642160601b6044820152606401610deb565b601254601154612ccc9190613b9c565b4211158015612cdd57506013546001145b15612d2357612ced600d88611fa0565b506040516001600160a01b038816907f8c21268f4379683ad2b81c32b4357f44a17e83e73d741ba6e8c23e085e57135190600090a25b50601a5460ff16612f32565b612d3b6009600a613b57565b8611612d4a57612d4a8861251c565b601754612d578785613b9c565b1115612d985760405162461bcd60e51b815260206004820152601060248201526f3bb430b63290383937ba32b1ba34b7b760811b6044820152606401610deb565b612da36007896124fa565b612e0d576001600160a01b03881660009081526003602052604090205442101580612dd0575060275460ff165b612e0d5760405162461bcd60e51b815260206004820152600e60248201526d53656e64657220696e204c6f636b60901b6044820152606401610deb565b612e18600d896124fa565b15612e655760405162461bcd60e51b815260206004820152601b60248201527f53656e646572206164647265737320626c61636b6c69737465642100000000006044820152606401610deb565b612e70600d886124fa565b15612ebd5760405162461bcd60e51b815260206004820152601e60248201527f526563697069656e74206164647265737320626c61636b6c69737465642100006044820152606401610deb565b601254601154612ecd9190613b9c565b4211158015612ede57506013546001145b15612f2457612eee600d89611fa0565b506040516001600160a01b038916907f8c21268f4379683ad2b81c32b4357f44a17e83e73d741ba6e8c23e085e57135190600090a25b50601a5462010000900460ff165b601a546001600160a01b03898116600160301b9092041614801590612f5a5750602b5460ff16155b8015612f69575060255460ff16155b8015612f725750835b15612f7f57612f7f6123a7565b6000612f9b8783601a60039054906101000a900460ff16613681565b601a54909150600090612fcf9089908590612fca9060ff6401000000008204811691600160281b900416613bd6565b613681565b90506000612fdd8284613b9c565b612fe7908a613b85565b9050612ff38b8a6134f5565b3060009081526001602052604081208054849290613012908490613b9c565b92505081905550826016600082825461302b9190613b85565b9091555061303b90508a826135b6565b896001600160a01b03168b6001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161308091815260200190565b60405180910390a35050505050505050505050565b600081815260018301602052604081205480156131785760006130b9600183613b85565b85549091506000906130cd90600190613b85565b905060008660000182815481106130e6576130e6613d6d565b906000526020600020015490508087600001848154811061310957613109613d6d565b60009182526020808320909101929092558281526001890190915260409020849055865487908061313c5761313c613dfc565b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610dac565b6000915050610dac565b601b5461319a9030906001600160a01b031683611fbc565b60408051600280825260608201835260009260208301908036833701905050905030816000815181106131cf576131cf613d6d565b6001600160a01b03928316602091820292909201810191909152601b54604080516302768aa360e51b815290519190931692634ed154609260048083019391928290030181865afa158015613228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061324c9190613d50565b8160018151811061325f5761325f613d6d565b6001600160a01b039283166020918202929092010152601b5460405163b43d9bbb60e01b815291169063b43d9bbb906132a5908590600090869030904290600401613e12565b600060405180830381600087803b1580156132bf57600080fd5b505af11580156132d3573d6000803e3d6000fd5b505050505050565b80602460008282546132ed9190613b9c565b9091555050601b5461330a9030906001600160a01b031684611fbc565b601b54604051633994a6ad60e21b8152306004820181905260248201859052600060448301819052606483015260848201524260a48201526001600160a01b039091169063e6529ab490839060c40160606040518083038185885af1158015613377573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061339c9190613e4e565b5050505050565b601f546000906064906133b99060ff1684613b66565b6133c39190613bb4565b905060006133d18284613b85565b905081602060008282546133e59190613b9c565b90915550508015611a6c5780601d60008282546134029190613b9c565b9091555060009050613412611c28565b90508060000361343957816020600082825461342e9190613b9c565b909155506134699050565b80613448600160401b84613b66565b6134529190613bb4565b601c60008282546134639190613b9c565b90915550505b50505050565b815460009082106134cd5760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610deb565b8260000182815481106134e2576134e2613d6d565b9060005260206000200154905092915050565b6001600160a01b038216600090815260016020526040812054613519908390613b85565b905061352483611514565b15613549576001600160a01b0390921660009081526001602052604090209190915550565b60006135548461230c565b6001600160a01b0385166000908152600160205260409020839055601c54909150613580908390613b66565b6001600160a01b038516600090815260216020908152604080832093909355602290529081208054839290613463908490613b9c565b6001600160a01b0382166000908152600160205260408120546135da908390613b9c565b90506135e583611514565b1561360a576001600160a01b0390921660009081526001602052604090209190915550565b60006136158461230c565b905081601c546136259190613b66565b6001600160a01b03851660009081526021602090815260408083209390935560229052908120805483929061365b908490613b9c565b9091555050506001600160a01b0390921660009081526001602052604090209190915550565b60006127108260ff168460ff16866136999190613b66565b6136a39190613b66565b6136ad9190613bb4565b949350505050565b600060208083528351808285015260005b818110156136e2578581018301518582016040015282016136c6565b818111156136f4576000604083870101525b50601f01601f1916929092016040019392505050565b6001600160a01b03811681146112b157600080fd5b6000806040838503121561373257600080fd5b823561373d8161370a565b946020939093013593505050565b80151581146112b157600080fd5b60006020828403121561376b57600080fd5b8135611fb58161374b565b60008060006060848603121561378b57600080fd5b83356137968161370a565b925060208401356137a68161370a565b929592945050506040919091013590565b6000602082840312156137c957600080fd5b8135611fb58161370a565b6000602082840312156137e657600080fd5b5035919050565b803560ff811681146137fe57600080fd5b919050565b60008060008060008060c0878903121561381c57600080fd5b613825876137ed565b9550613833602088016137ed565b9450613841604088016137ed565b935061384f606088016137ed565b925061385d608088016137ed565b915061386b60a088016137ed565b90509295509295509295565b60006020828403121561388957600080fd5b611fb5826137ed565b600080604083850312156138a557600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126138db57600080fd5b813567ffffffffffffffff808211156138f6576138f66138b4565b604051601f8301601f19908116603f0116810190828211818310171561391e5761391e6138b4565b8160405283815286602085880101111561393757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561396a57600080fd5b823567ffffffffffffffff8082111561398257600080fd5b61398e868387016138ca565b935060208501359150808211156139a457600080fd5b506139b1858286016138ca565b9150509250929050565b600080604083850312156139ce57600080fd5b82356139d98161370a565b915060208301356139e98161370a565b809150509250929050565b600181811c90821680613a0857607f821691505b602082108103611c8857634e487b7160e01b600052602260045260246000fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600181815b80851115613aae578160001904821115613a9457613a94613a5d565b80851615613aa157918102915b93841c9390800290613a78565b509250929050565b600082613ac557506001610dac565b81613ad257506000610dac565b8160018114613ae85760028114613af257613b0e565b6001915050610dac565b60ff841115613b0357613b03613a5d565b50506001821b610dac565b5060208310610133831016604e8410600b8410161715613b31575081810a610dac565b613b3b8383613a73565b8060001904821115613b4f57613b4f613a5d565b029392505050565b6000611fb560ff841683613ab6565b6000816000190483118215151615613b8057613b80613a5d565b500290565b600082821015613b9757613b97613a5d565b500390565b60008219821115613baf57613baf613a5d565b500190565b600082613bd157634e487b7160e01b600052601260045260246000fd5b500490565b600060ff821660ff84168060ff03821115613bf357613bf3613a5d565b019392505050565b601f821115611a6c57600081815260208120601f850160051c81016020861015613c225750805b601f850160051c820191505b818110156132d357828155600101613c2e565b815167ffffffffffffffff811115613c5b57613c5b6138b4565b613c6f81613c6984546139f4565b84613bfb565b602080601f831160018114613ca45760008415613c8c5750858301515b600019600386901b1c1916600185901b1785556132d3565b600085815260208120601f198616915b82811015613cd357888601518255948401946001909101908401613cb4565b5085821015613cf15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060018201613d1357613d13613a5d565b5060010190565b600060208284031215613d2c57600080fd5b5051919050565b600060208284031215613d4557600080fd5b8151611fb58161374b565b600060208284031215613d6257600080fd5b8151611fb58161370a565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015613dbc5781516001600160a01b031687529582019590820190600101613d97565b509495945050505050565b848152608060208201526000613de06080830186613d83565b6001600160a01b03949094166040830152506060015292915050565b634e487b7160e01b600052603160045260246000fd5b85815284602082015260a060408201526000613e3160a0830186613d83565b6001600160a01b0394909416606083015250608001529392505050565b600080600060608486031215613e6357600080fd5b835192506020840151915060408401519050925092509256fea2646970667358221220f788e1992290c2c8d75f07668172ff9e3ce6846f2b1d951835fced6bf338553364736f6c634300080f0033