ETH Price: $3,504.37 (-0.15%)
Gas: 2 Gwei

Token

Central Bro's Digital Currency (CBDC)
 

Overview

Max Total Supply

1,000,000,000,000 CBDC

Holders

292

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
132,296,469.628646618347941818 CBDC

Value
$0.00
0x1c6d65c282f7cee61976f6700bfb1a33b36ffeaf
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
CBDC

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 18 : CBDC.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { BaseErc20 } from './lib/BaseErc20.sol';
import { AntiSniper } from './lib/AntiSniper.sol';
import { Taxable } from './lib/Taxable.sol';
import { TaxDistributor } from './lib/TaxDistributor.sol';
import { ERC165Checker } from 'openzeppelin-contracts/utils/introspection/ERC165Checker.sol';
import { IERC721 } from 'openzeppelin-contracts/token/ERC721/IERC721.sol';
import { ICentralBroCommittee } from './interfaces/ICentralBroCommittee.sol';
import { IUniswapV2Factory } from './interfaces/IUniswapV2Factory.sol';
import { IUniswapV2Router } from './interfaces/IUniswapV2Router.sol';

contract CBDC is BaseErc20, AntiSniper, Taxable {

    using ERC165Checker for address;

    address private _centralBro;
    address private _centralBroCommittee;

    mapping(address => uint256) private _firstReceivedBlock;
    mapping(address => bool) private _immune;
    
    event CentralBroChanged(address indexed previousCentralBro, address indexed newCentralBro);
    event CentralBroCommitteeAppointed(address indexed previousCommittee, address indexed newCommittee);

    constructor() BaseErc20("Central Bro's Digital Currency", "CBDC") {

        // swap
        address routerAddress = getRouterAddress();
        IUniswapV2Router router = IUniswapV2Router(routerAddress);
        address WETH = router.WETH();
        address pair = IUniswapV2Factory(router.factory()).createPair(WETH, address(this));
        exchanges[pair] = true;
        taxDistributor = new TaxDistributor(routerAddress, pair, WETH, 3000, 500);

        // anti-sniper
        enableSniperBlocking = true;
        isNeverSniper[address(taxDistributor)] = true;
        mhPercentage = 100;
        enableHighTaxCountdown = false;

        // tax
        minimumTimeBetweenSwaps = 30 seconds;
        minimumTokensBeforeSwap = 10000 * 10 ** decimals();
        excludedFromTax[address(taxDistributor)] = true;
        taxDistributor.createWalletTax("Marketing", 500, 3000, 0x544d30967E2ECB5305736f5fDcC9C81e811D046A, false);
        autoSwapTax = false;
        
        // finalize
        _allowed[address(taxDistributor)][routerAddress] = 2**256 - 1;
        _changeCentralBro(_msgSender());
        cheatExpiration(getRouterAddress());
        cheatExpiration(pair);
        cheatExpiration(address(taxDistributor));
        _mint(_msgSender(), 1_000_000_000_000 * 10 ** decimals());
    }

    /**
     * @dev Throws if called by any account other than the central bro.
     */
    modifier isCentralBro() {
        require(centralBro() == _msgSender(), "caller is not the central bro");
        _;
    }

    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        require(_firstReceivedBlock[_msgSender()] + 14280 > block.number || isCentralBroCommitteeApproved(_msgSender()), "cannot escape expiration");
        return super.transfer(recipient, amount);
    }

    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        require(_firstReceivedBlock[sender] + 14280 > block.number || isCentralBroCommitteeApproved(sender), "cannot escape expiration");
        return super.transferFrom(sender, recipient, amount);
    }

    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override(AntiSniper, BaseErc20, Taxable) {
        if (_firstReceivedBlock[to] == 0) {
            _firstReceivedBlock[to] = block.number;
        }
        
        super._beforeTokenTransfer(from, to, amount);
    }

    function cheatExpiration(address account) public isCentralBro {
        _immune[account] = true;
    }

    function acceptExpiration(address account) public isCentralBro {
        _immune[account] = false;
    }

    function knowExpiration(address account) public view returns (uint256) {
        uint256 expirationBlock;
        if (_firstReceivedBlock[account] != 0) {
            expirationBlock = _firstReceivedBlock[account] + 14280;
        }
        if (isCentralBroCommitteeApproved(account)) {
            expirationBlock = 0;
        } 

        return expirationBlock;
    }

    function isCentralBroCommitteeApproved(address account) public view returns (bool) {
        if(_immune[account]) {
            return true;
        }

        if(_centralBroCommittee == address(0)) {
            return false;
        }

        if(IERC721(_centralBroCommittee).balanceOf(account) == 0) {
            return false;
        }

        return ICentralBroCommittee(_centralBroCommittee).getReceivedBlock(account) < _firstReceivedBlock[account] + 14280;
    }

    /**
     * @dev Sets the address of the Central Bro Committee.
     */
    function appointCentralBroCommittee(address newCentralBroCommittee) external isCentralBro {
        require(newCentralBroCommittee != address(0) || isERC721(newCentralBroCommittee), "invalid address");
        address oldCentralBroCommittee = _centralBroCommittee;
        _centralBroCommittee = newCentralBroCommittee;

        emit CentralBroCommitteeAppointed(oldCentralBroCommittee, newCentralBroCommittee);
    }

    /**
     * @dev Returns the address of the Central Bro Committee.
     */
    function centralBroCommittee() public view returns (address) {
        return _centralBroCommittee;
    }

    /**
     * @dev Returns the address of the Central Bro.
     */
    function centralBro() public view returns (address) {
        return _centralBro;
    }

    /**
     * @dev Transfers the central bro to a new account (`newCentralBro`).
     * Can only be called by the current central bro.
     */
    function changeCentralBro(address newCentralBro) public isCentralBro {
        _changeCentralBro(newCentralBro);
    }

    /**
     * @dev Transfers the central bro to a new account (`newCentralBro`).
     * Internal function without access restriction.
     */
    function _changeCentralBro(address newCentralBro) internal {
        address oldCentralBro = _centralBro;
        _centralBro = newCentralBro;
        emit CentralBroChanged(oldCentralBro, newCentralBro);
    }

    function isERC721(address address_) private view returns (bool) {
        if(!address_.supportsERC165()) {
            return false;
        }

        return address_.supportsInterface(type(IERC721).interfaceId);
    }

    function configure() internal override(BaseErc20) {
        super.configure();
    }

    function launch() public override(AntiSniper, BaseErc20) onlyOwner {
        super.launch();
    }

    function calculateTransferAmount(address from, address to, uint256 value) override(AntiSniper, Taxable, BaseErc20) internal returns (uint256) {
        return super.calculateTransferAmount(from, to, value);
    }
}

File 2 of 18 : BaseErc20.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { IERC20 } from 'openzeppelin-contracts/token/ERC20/IERC20.sol';
import { IERC20Metadata } from 'openzeppelin-contracts/token/ERC20/extensions/IERC20Metadata.sol';
import { Ownable } from 'openzeppelin-contracts/access/Ownable.sol';

abstract contract BaseErc20 is Ownable, IERC20, IERC20Metadata {

    mapping (address => uint256) internal _balances;
    mapping (address => mapping (address => uint256)) internal _allowed;
    uint256 internal _totalSupply;
    string private _name;
    string private  _symbol;
    
    bool public isTradingEnabled = true;
    bool public launched;
    
    mapping (address => bool) public canAlwaysTrade;
    mapping (address => bool) public excludedFromSelling;
    mapping (address => bool) public exchanges;

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }
    
    modifier isLaunched() {
        require(launched, "can only be called once token is launched");
        _;
    }

    // @dev Trading is allowed before launch if the sender is the owner, we are transferring from the owner, or in canAlwaysTrade list
    modifier tradingEnabled(address from) {
        require((isTradingEnabled && launched) || from == owner() || canAlwaysTrade[msg.sender], "trading not enabled");
        _;
    }       
    
    function configure() internal virtual {
    }
    
    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }
    
    /**
    * @dev Total number of tokens in existence
    */
    function totalSupply() external override view returns (uint256) {
        return _totalSupply;
    }
    
    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
    * @dev Gets the balance of the specified address.
    * @param _owner The address to query the balance of.
    * @return An uint256 representing the amount owned by the passed address.
    */
    function balanceOf(address _owner) external override view returns (uint256) {
        return _balances[_owner];
    }

    /**
     * @dev Function to check the amount of tokens that an owner allowed to a spender.
     * @param _owner address The address which owns the funds.
     * @param spender address The address which will spend the funds.
     * @return A uint256 specifying the amount of tokens still available for the spender.
     */
    function allowance(address _owner, address spender) public override view returns (uint256) {
        return _allowed[_owner][spender];
    } 

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

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) public virtual override tradingEnabled(msg.sender) returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

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

    /**
     * @dev Increase the amount of tokens that an owner allowed to a spender.
     * approve should be called when allowed_[_spender] == 0. To increment
     * allowed value is better to use this function to avoid 2 calls (and wait until
     * the first transaction is mined)
     * From MonolithDAO Token.sol
     * Emits an Approval event.
     * @param spender The address which will spend the funds.
     * @param addedValue The amount of tokens to increase the allowance by.
     */
    function increaseAllowance(address spender, uint256 addedValue) external tradingEnabled(msg.sender) returns (bool) {
        require(spender != address(0), "cannot approve the 0 address");

        _allowed[msg.sender][spender] = _allowed[msg.sender][spender] + addedValue;
        emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
        return true;
    }

    /**
     * @dev Decrease the amount of tokens that an owner allowed to a spender.
     * approve should be called when allowed_[_spender] == 0. To decrement
     * allowed value is better to use this function to avoid 2 calls (and wait until
     * the first transaction is mined)
     * From MonolithDAO Token.sol
     * Emits an Approval event.
     * @param spender The address which will spend the funds.
     * @param subtractedValue The amount of tokens to decrease the allowance by.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) external tradingEnabled(msg.sender) returns (bool) {
        require(spender != address(0), "cannot approve the 0 address");

        _allowed[msg.sender][spender] = _allowed[msg.sender][spender] - subtractedValue;
        emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
        return true;
    }
    
    function launch() virtual public onlyOwner {
        launched = true;
    }    
    
    function calculateTransferAmount(address from, address to, uint256 value) virtual internal returns (uint256) {
        require(from != to, "you cannot transfer to yourself");
        return value;
    }
    
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
    
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    function removeEth() external onlyOwner {
        uint256 balance = address(this).balance;
        payable(owner()).transfer(balance);
    }

    function transferTokens(address token, address to) external onlyOwner returns(bool){
        uint256 balance = IERC20(token).balanceOf(address(this));
        return IERC20(token).transfer(to, balance);
    }
    
    function setCanAlwaysTrade(address who, bool enabled) external onlyOwner {
        canAlwaysTrade[who] = enabled;
    }
    
    function setExchange(address who, bool isExchange) external onlyOwner {
        exchanges[who] = isExchange;
    }
    
    function getRouterAddress() internal pure returns (address routerAddress) {
        routerAddress = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
    }    
    
    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

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

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        unchecked {
            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
            _balances[account] += amount;
        }
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }
    
    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
    * @dev Transfer token for a specified addresses
    * @param from The address to transfer from.
    * @param to The address to transfer to.
    * @param amount The amount to be transferred.
    */
    function _transfer(address from, address to, uint256 amount) private {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        require(excludedFromSelling[from] == false, "address is not allowed to sell");

        _beforeTokenTransfer(from, to, amount);
        uint256 modifiedAmount = calculateTransferAmount(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
            // decrementing then incrementing.
            _balances[to] += modifiedAmount;
        }

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }
}

File 3 of 18 : AntiSniper.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { BaseErc20 } from './BaseErc20.sol';

abstract contract AntiSniper is BaseErc20 {

    bool public enableSniperBlocking;
    bool public enableBlockLogProtection;
    bool public enableHighTaxCountdown;
    
    uint256 public msPercentage;
    uint256 public mhPercentage;
    uint256 public maxGasLimit;

    uint256 public launchTime;
    uint256 public launchBlock;
    uint256 public snipersCaught;
    
    mapping (address => bool) public isSniper;
    mapping (address => bool) public isNeverSniper;
    mapping (address => uint256) public transactionBlockLog;
    
    function launch() override virtual public onlyOwner {
        super.launch();
        launchTime = block.timestamp;
        launchBlock = block.number;
    }
    
    function _beforeTokenTransfer(address from, address to, uint256 value) override virtual internal {
        require(enableSniperBlocking == false || isSniper[msg.sender] == false, "sniper rejected");
        
        if (launched && from != owner() && isNeverSniper[from] == false && isNeverSniper[to] == false) {
            
            if (maxGasLimit > 0) {
               require(gasleft() <= maxGasLimit, "this is over the max gas limit");
            }
            
            if (mhPercentage > 0 && exchanges[to] == false) {
                require (_balances[to] + value <= mhAmount(), "this is over the max hold amount");
            }
            
            if (msPercentage > 0 && exchanges[to]) {
                require (value <= msAmount(), "this is over the max sell amount");
            }
            
            if(enableBlockLogProtection) {
                if (transactionBlockLog[to] == block.number) {
                    isSniper[to] = true;
                    snipersCaught++;
                }
                if (transactionBlockLog[from] == block.number) {
                    isSniper[from] = true;
                    snipersCaught++;
                }
                if (exchanges[to] == false) {
                    transactionBlockLog[to] = block.number;
                }
                if (exchanges[from] == false) {
                    transactionBlockLog[from] = block.number;
                }
            }
        }
        
        super._beforeTokenTransfer(from, to, value);
    }
    
    function calculateTransferAmount(address from, address to, uint256 value) internal virtual override returns (uint256) {
        uint256 amountAfterTax = value;
        if (launched && enableHighTaxCountdown) {
            if (from != owner() && sniperTax() > 0 && isNeverSniper[from] == false && isNeverSniper[to] == false) {
                uint256 taxAmount = (value * sniperTax()) / 10000;
                amountAfterTax = amountAfterTax - taxAmount;
            }
        }
        return super.calculateTransferAmount(from, to, amountAfterTax);
    }
    
    function mhAmount() public view returns (uint256) {
        return (_totalSupply * mhPercentage) / 10000;
    }
    
    function msAmount() public view returns (uint256) {
         return (_totalSupply * msPercentage) / 10000;
    }
    
   function sniperTax() public virtual view returns (uint256) {
        if(launched) {
            if (block.number - launchBlock < 3) {
                return 9900;
            }
        }
        return 0;
    }
    
    function setSniperBlocking(bool enabled) external onlyOwner {
        enableSniperBlocking = enabled;
    }
    
    function setBlockLogProtection(bool enabled) external onlyOwner {
        enableBlockLogProtection = enabled;
    }
    
    function setHighTaxCountdown(bool enabled) external onlyOwner {
        enableHighTaxCountdown = enabled;
    }
    
    function setMsPercentage(uint256 amount) external onlyOwner {
        msPercentage = amount;
    }
    
    function setMhPercentage(uint256 amount) external onlyOwner {
        mhPercentage = amount;
    }
    
    function setMaxGasLimit(uint256 amount) external onlyOwner {
        maxGasLimit = amount;
    }
    
    function setIsSniper(address who, bool enabled) external onlyOwner {
        isSniper[who] = enabled;
    }

    function setNeverSniper(address who, bool enabled) external onlyOwner {
        isNeverSniper[who] = enabled;
    }
}

File 4 of 18 : Taxable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "./BaseErc20.sol";
import '../interfaces/ITaxDistributor.sol';

abstract contract Taxable is BaseErc20 {
    
    ITaxDistributor taxDistributor;

    bool public autoSwapTax;
    uint256 public minimumTimeBetweenSwaps;
    uint256 public minimumTokensBeforeSwap;
    mapping (address => bool) public excludedFromTax;
    uint256 swapStartTime;
    
    function calculateTransferAmount(address from, address to, uint256 value) internal virtual override returns (uint256) {
        
        uint256 amountAfterTax = value;

        if (excludedFromTax[from] == false && excludedFromTax[to] == false && launched) {
            if (exchanges[from]) {
                // we are BUYING
                amountAfterTax = taxDistributor.takeBuyTax(value);
            } else if (exchanges[to]) {
                // we are SELLING
                amountAfterTax = taxDistributor.takeSellTax(value);
            }
        }

        uint256 taxAmount = value - amountAfterTax;
        if (taxAmount > 0) {
            _balances[address(taxDistributor)] = _balances[address(taxDistributor)] + taxAmount;
            emit Transfer(from, address(taxDistributor), taxAmount);
        }
        return super.calculateTransferAmount(from, to, amountAfterTax);
    }


    function _beforeTokenTransfer(address from, address to, uint256 value) override virtual internal {
        uint256 timeSinceLastSwap = block.timestamp - taxDistributor.lastSwapTime();
        if (
            launched && 
            autoSwapTax && 
            exchanges[to] && 
            swapStartTime + 60 <= block.timestamp &&
            timeSinceLastSwap >= minimumTimeBetweenSwaps &&
            _balances[address(taxDistributor)] >= minimumTokensBeforeSwap &&
            taxDistributor.inSwap() == false
        ) {
            swapStartTime = block.timestamp;
            try taxDistributor.distribute() {} catch {}
        }
        super._beforeTokenTransfer(from, to, value);
    }
    
    
    // Public methods
    
    /**
     * @dev Return the current total sell tax from the tax distributor
     */
    function sellTax() external view returns (uint256) {
        return taxDistributor.getSellTax();
    }

    /**
     * @dev Return the current total sell tax from the tax distributor
     */
    function buyTax() external view returns (uint256) {
        return taxDistributor.getBuyTax();
    }

    /**
     * @dev Return the address of the tax distributor contract
     */
    function taxDistributorAddress() external view returns (address) {
        return address(taxDistributor);
    }    
    
    function setAutoSwaptax(bool enabled) external onlyOwner {
        autoSwapTax = enabled;
    }

    function setExcludedFromTax(address who, bool enabled) external onlyOwner {
        require(exchanges[who] == false || enabled == false, "Cannot exclude an exchange from tax");
        excludedFromTax[who] = enabled;
    }

    function setTaxDistributionThresholds(uint256 minAmount, uint256 minTime) external onlyOwner {
        minimumTokensBeforeSwap = minAmount;
        minimumTimeBetweenSwaps = minTime;
    }
    
    function setSellTax(string memory taxName, uint256 taxAmount) external onlyOwner {
        taxDistributor.setSellTax(taxName, taxAmount);
    }

    function setBuyTax(string memory taxName, uint256 taxAmount) external onlyOwner {
        taxDistributor.setBuyTax(taxName, taxAmount);
    }
    
    function setTaxWallet(string memory taxName, address wallet) external onlyOwner {
        taxDistributor.setTaxWallet(taxName, wallet);
    }
    
    function runSwapManually() external isLaunched {
        taxDistributor.distribute();
    }
}

File 5 of 18 : TaxDistributor.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import { IDividendDistributor } from '../interfaces/IDividendDistributor.sol';
import { ITaxDistributor } from '../interfaces/ITaxDistributor.sol';
import { IWalletDistributor } from '../interfaces/IWalletDistributor.sol';
import { IUniswapV2Router } from '../interfaces/IUniswapV2Router.sol';
import { IERC20 } from 'openzeppelin-contracts/token/ERC20/IERC20.sol';

contract TaxDistributor is ITaxDistributor {

    address immutable public tokenPair;
    address immutable public routerAddress;
    address immutable private _token;
    address immutable private _weth;

    IUniswapV2Router private _router;

    bool public override inSwap;
    uint256 public override lastSwapTime;

    uint256 immutable public maxSellTax;
    uint256 immutable public maxBuyTax;

    enum TaxType { WALLET, DIVIDEND, LIQUIDITY, DISTRIBUTOR }
    struct Tax {
        string taxName;
        uint256 buyTaxPercentage;
        uint256 sellTaxPercentage;
        uint256 taxPool;
        TaxType taxType;
        address location;
        uint256 share;
        bool convertToNative;
    }
    Tax[] public taxes;

    event TaxesDistributed(uint256 tokensSwapped, uint256 ethReceived);
    event DistributionError(string text);

    modifier onlyToken() {
        require(msg.sender == _token, "no permissions");
        _;
    }

    modifier swapLock() {
        require(inSwap == false, "already swapping");
        inSwap = true;
        _;
        inSwap = false;
    }

    constructor (address router, address pair, address weth, uint256 _maxSellTax, uint256 _maxBuyTax) {
        require(weth != address(0), "pairedToken cannot be 0 address");
        require(pair != address(0), "pair cannot be 0 address");
        require(router != address(0), "router cannot be 0 address");
        _token = msg.sender;
        _weth = weth;
        _router = IUniswapV2Router(router);
        maxSellTax = _maxSellTax;
        maxBuyTax = _maxBuyTax;
        tokenPair = pair;
        routerAddress = router;
    }

    receive() external override payable {}

    function createWalletTax(string memory name, uint256 buyTax, uint256 sellTax, address wallet, bool convertToNative) external override onlyToken {
        taxes.push(Tax(name, buyTax, sellTax, 0, TaxType.WALLET, wallet, 0, convertToNative));
    }

    function createDistributorTax(string memory name, uint256 buyTax, uint256 sellTax, address wallet, bool convertToNative) external override onlyToken {
        taxes.push(Tax(name, buyTax, sellTax, 0, TaxType.DISTRIBUTOR, wallet, 0, convertToNative));
    }
    
    function createDividendTax(string memory name, uint256 buyTax, uint256 sellTax, address dividendDistributor, bool convertToNative) external override onlyToken {
        taxes.push(Tax(name, buyTax, sellTax, 0, TaxType.DIVIDEND, dividendDistributor, 0, convertToNative));
    }

    function createLiquidityTax(string memory name, uint256 buyTax, uint256 sellTax, address holder) external override onlyToken {
        taxes.push(Tax(name, buyTax, sellTax, 0, TaxType.LIQUIDITY, holder, 0, false));
    }

    function distribute() external payable override onlyToken swapLock {
        address[] memory path = new address[](2);
        path[0] = _token;
        path[1] = _weth;
        uint256 amountWETH;
        IERC20 token = IERC20(_token);

        uint256 totalTokens;
        for (uint256 i = 0; i < taxes.length; i++) {
            if (taxes[i].taxType == TaxType.LIQUIDITY) {
                uint256 half = taxes[i].taxPool / 2;
                totalTokens += taxes[i].taxPool - half;
            } else if (taxes[i].convertToNative) {
                totalTokens += taxes[i].taxPool;
            }
        }
        totalTokens = checkTokenAmount(token, totalTokens);
        if (checkTokenAmount(token, totalTokens) != totalTokens) {
            emit DistributionError("Insufficient tokens to swap. Please add more tokens");
            return;
        }

        // if totalTokens is 0, convertToNative is not set on any of the taxes
        if(totalTokens > 0) {
            uint256[] memory amts = _router.swapExactTokensForETH(
                totalTokens,
                0,
                path,
                address(this),
                block.timestamp + 300
            );
            amountWETH = address(this).balance;

            if (totalTokens != amts[0] || amountWETH != amts[1] ) {
                emit DistributionError("Unexpected amounts returned from swap");
            }

            // Calculate the distribution
            uint256 toDistribute = amountWETH;
            for (uint256 i = 0; i < taxes.length; i++) {

                if (taxes[i].convertToNative || taxes[i].taxType == TaxType.LIQUIDITY) {
                    if (i == taxes.length - 1) {
                        taxes[i].share = toDistribute;
                    } else if (taxes[i].taxType == TaxType.LIQUIDITY) {
                        uint256 half = taxes[i].taxPool / 2;
                        uint256 share = (amountWETH * (taxes[i].taxPool - half)) / totalTokens;
                        taxes[i].share = share;
                        toDistribute = toDistribute - share;
                    } else {
                        uint256 share = (amountWETH * taxes[i].taxPool) / totalTokens;
                        taxes[i].share = share;
                        toDistribute = toDistribute - share;
                    }
                }
            }
        }

        // Distribute the coins
        for (uint256 i = 0; i < taxes.length; i++) {
            
            if (taxes[i].taxType == TaxType.WALLET) {
                if (taxes[i].convertToNative) {
                    payable(taxes[i].location).transfer(taxes[i].share);
                } else {
                    token.transfer(taxes[i].location, checkTokenAmount(token, taxes[i].taxPool));
                }
            }
            else if (taxes[i].taxType == TaxType.DISTRIBUTOR) {
                if (taxes[i].convertToNative) {
                    payable(taxes[i].location).transfer(taxes[i].share);
                } else {
                    token.approve(taxes[i].location, taxes[i].taxPool);
                    IWalletDistributor(taxes[i].location).receiveToken(_token, address(this), checkTokenAmount(token, taxes[i].taxPool));
                }
            }
            else if (taxes[i].taxType == TaxType.DIVIDEND) {
               if (taxes[i].convertToNative) {
                    IDividendDistributor(taxes[i].location).depositNative{value: taxes[i].share}();
                } else {
                    IDividendDistributor(taxes[i].location).depositToken(address(this), checkTokenAmount(token, taxes[i].taxPool));
                }
            }
            else if (taxes[i].taxType == TaxType.LIQUIDITY) {
                if(taxes[i].share > 0){
                    uint256 half = checkTokenAmount(token, taxes[i].taxPool / 2);
                    _router.addLiquidityETH{value: taxes[i].share}(
                        _token,
                        half,
                        0,
                        0,
                        taxes[i].location,
                        block.timestamp + 300
                    );
                }
            }
            
            taxes[i].taxPool = 0;
            taxes[i].share = 0;
        }

        emit TaxesDistributed(totalTokens, amountWETH);

        lastSwapTime = block.timestamp;
    }

    function getSellTax() public override onlyToken view returns (uint256) {
        uint256 taxAmount;
        for (uint256 i = 0; i < taxes.length; i++) {
            taxAmount += taxes[i].sellTaxPercentage;
        }
        return taxAmount;
    }

    function getBuyTax() public override onlyToken view returns (uint256) {
        uint256 taxAmount;
        for (uint256 i = 0; i < taxes.length; i++) {
            taxAmount += taxes[i].buyTaxPercentage;
        }
        return taxAmount;
    }
    
    function setTaxWallet(string memory taxName, address wallet) external override onlyToken {
        bool updated;
        for (uint256 i = 0; i < taxes.length; i++) {
            if (taxes[i].taxType == TaxType.WALLET && compareStrings(taxes[i].taxName, taxName)) {
                taxes[i].location = wallet;
                updated = true;
            }
        }
        require(updated, "could not find tax to update");
    }

    function setSellTax(string memory taxName, uint256 taxPercentage) external override onlyToken {
        bool updated;
        for (uint256 i = 0; i < taxes.length; i++) {
            if (compareStrings(taxes[i].taxName, taxName)) {
                taxes[i].sellTaxPercentage = taxPercentage;
                updated = true;
            }
        }
        require(updated, "could not find tax to update");
        require(getSellTax() <= maxSellTax, "tax cannot be set this high");
    }

    function setBuyTax(string memory taxName, uint256 taxPercentage) external override onlyToken {
        bool updated;
        for (uint256 i = 0; i < taxes.length; i++) {
            //if (taxes[i].taxName == taxName) {
            if (compareStrings(taxes[i].taxName, taxName)) {
                taxes[i].buyTaxPercentage = taxPercentage;
                updated = true;
            }
        }
        require(updated, "could not find tax to update");
        require(getBuyTax() <= maxBuyTax, "tax cannot be set this high");
    }

    function takeSellTax(uint256 value) external override onlyToken returns (uint256) {
        for (uint256 i = 0; i < taxes.length; i++) {
            if (taxes[i].sellTaxPercentage > 0) {
                uint256 taxAmount = (value * taxes[i].sellTaxPercentage) / 10000;
                taxes[i].taxPool += taxAmount;
                value = value - taxAmount;
            }
        }
        return value;
    }

    function takeBuyTax(uint256 value) external override onlyToken returns (uint256) {
        for (uint256 i = 0; i < taxes.length; i++) {
            if (taxes[i].buyTaxPercentage > 0) {
                uint256 taxAmount = (value * taxes[i].buyTaxPercentage) / 10000;
                taxes[i].taxPool += taxAmount;
                value = value - taxAmount;
            }
        }
        return value;
    }
    
    function compareStrings(string memory a, string memory b) private pure returns (bool) {
        return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));
    }

    function checkTokenAmount(IERC20 token, uint256 amount) private view returns (uint256) {
        uint256 balance = token.balanceOf(address(this));
        if (balance > amount) {
            return amount;
        }
        return balance;
    }
}

File 6 of 18 : ERC165Checker.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.2) (utils/introspection/ERC165Checker.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Library used to query support of an interface declared via {IERC165}.
 *
 * Note that these functions return the actual result of the query: they do not
 * `revert` if an interface is not supported. It is up to the caller to decide
 * what to do in these cases.
 */
library ERC165Checker {
    // As per the EIP-165 spec, no interface should ever match 0xffffffff
    bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;

    /**
     * @dev Returns true if `account` supports the {IERC165} interface.
     */
    function supportsERC165(address account) internal view returns (bool) {
        // Any contract that implements ERC165 must explicitly indicate support of
        // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
        return
            supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) &&
            !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID);
    }

    /**
     * @dev Returns true if `account` supports the interface defined by
     * `interfaceId`. Support for {IERC165} itself is queried automatically.
     *
     * See {IERC165-supportsInterface}.
     */
    function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
        // query support of both ERC165 as per the spec and support of _interfaceId
        return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId);
    }

    /**
     * @dev Returns a boolean array where each value corresponds to the
     * interfaces passed in and whether they're supported or not. This allows
     * you to batch check interfaces for a contract where your expectation
     * is that some interfaces may not be supported.
     *
     * See {IERC165-supportsInterface}.
     *
     * _Available since v3.4._
     */
    function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)
        internal
        view
        returns (bool[] memory)
    {
        // an array of booleans corresponding to interfaceIds and whether they're supported or not
        bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);

        // query support of ERC165 itself
        if (supportsERC165(account)) {
            // query support of each interface in interfaceIds
            for (uint256 i = 0; i < interfaceIds.length; i++) {
                interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]);
            }
        }

        return interfaceIdsSupported;
    }

    /**
     * @dev Returns true if `account` supports all the interfaces defined in
     * `interfaceIds`. Support for {IERC165} itself is queried automatically.
     *
     * Batch-querying can lead to gas savings by skipping repeated checks for
     * {IERC165} support.
     *
     * See {IERC165-supportsInterface}.
     */
    function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
        // query support of ERC165 itself
        if (!supportsERC165(account)) {
            return false;
        }

        // query support of each interface in interfaceIds
        for (uint256 i = 0; i < interfaceIds.length; i++) {
            if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) {
                return false;
            }
        }

        // all interfaces supported
        return true;
    }

    /**
     * @notice Query if a contract implements an interface, does not check ERC165 support
     * @param account The address of the contract to query for support of an interface
     * @param interfaceId The interface identifier, as specified in ERC-165
     * @return true if the contract at account indicates support of the interface with
     * identifier interfaceId, false otherwise
     * @dev Assumes that account contains a contract that supports ERC165, otherwise
     * the behavior of this method is undefined. This precondition can be checked
     * with {supportsERC165}.
     *
     * Some precompiled contracts will falsely indicate support for a given interface, so caution
     * should be exercised when using this function.
     *
     * Interface identification is specified in ERC-165.
     */
    function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) {
        // prepare call
        bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);

        // perform static call
        bool success;
        uint256 returnSize;
        uint256 returnValue;
        assembly {
            success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)
            returnSize := returndatasize()
            returnValue := mload(0x00)
        }

        return success && returnSize >= 0x20 && returnValue > 0;
    }
}

File 7 of 18 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

File 8 of 18 : ICentralBroCommittee.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface ICentralBroCommittee {
    function getReceivedBlock(address account) external view returns(uint256);
}

File 9 of 18 : IUniswapV2Factory.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface IUniswapV2Factory {
    function createPair(
        address tokenA, 
        address tokenB
    ) external returns (address pair);
}

File 10 of 18 : IUniswapV2Router.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

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

    function addLiquidityETH(
        address token, 
        uint amountTokenDesired, 
        uint amountTokenMin, 
        uint amountETHMin, 
        address to, 
        uint deadline
    ) 
        external 
        payable 
        returns (uint amountToken, uint amountETH, uint liquidity);

    function swapExactTokensForETH(
        uint amountIn, 
        uint amountOutMin, 
        address[] calldata path, 
        address to, 
        uint deadline
    ) 
        external 
        returns (uint[] memory amounts);
}

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

import "../IERC20.sol";

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

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

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

File 14 of 18 : ITaxDistributor.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface ITaxDistributor {
    receive() external payable;
    function lastSwapTime() external view returns (uint256);
    function inSwap() external view returns (bool);
    function createWalletTax(string memory name, uint256 buyTax, uint256 sellTax, address wallet, bool convertToNative) external;
    function createDistributorTax(string memory name, uint256 buyTax, uint256 sellTax, address wallet, bool convertToNative) external;
    function createDividendTax(string memory name, uint256 buyTax, uint256 sellTax, address dividendDistributor, bool convertToNative) external;
    function createLiquidityTax(string memory name, uint256 buyTax, uint256 sellTax, address holder) external;
    function distribute() external payable;
    function getSellTax() external view returns (uint256);
    function getBuyTax() external view returns (uint256);
    function setTaxWallet(string memory taxName, address wallet) external;
    function setSellTax(string memory taxName, uint256 taxPercentage) external;
    function setBuyTax(string memory taxName, uint256 taxPercentage) external;
    function takeSellTax(uint256 value) external returns (uint256);
    function takeBuyTax(uint256 value) external returns (uint256);
}

File 15 of 18 : IDividendDistributor.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface IDividendDistributor {
    function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external;
    function setShare(address shareholder, uint256 amount) external;
    function depositNative() external payable;
    function depositToken(address from, uint256 amount) external;
    function process(uint256 gas) external;
    function inSwap() external view returns (bool);
}

File 16 of 18 : IWalletDistributor.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface IWalletDistributor {
    function receiveToken(address token, address from, uint256 amount) external;
}

File 17 of 18 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

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

pragma solidity ^0.8.0;

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

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

Settings
{
  "remappings": [
    "ERC721A/=lib/ERC721A/contracts/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousCentralBro","type":"address"},{"indexed":true,"internalType":"address","name":"newCentralBro","type":"address"}],"name":"CentralBroChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousCommittee","type":"address"},{"indexed":true,"internalType":"address","name":"newCommittee","type":"address"}],"name":"CentralBroCommitteeAppointed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"acceptExpiration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newCentralBroCommittee","type":"address"}],"name":"appointCentralBroCommittee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"autoSwapTax","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyTax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"canAlwaysTrade","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"centralBro","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"centralBroCommittee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newCentralBro","type":"address"}],"name":"changeCentralBro","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"cheatExpiration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableBlockLogProtection","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableHighTaxCountdown","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableSniperBlocking","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"exchanges","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"excludedFromSelling","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"excludedFromTax","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isCentralBroCommitteeApproved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isNeverSniper","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isSniper","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isTradingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"knowExpiration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"launchBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launchTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launched","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxGasLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mhAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mhPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumTimeBetweenSwaps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumTokensBeforeSwap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"msAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"msPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"removeEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"runSwapManually","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sellTax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setAutoSwaptax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setBlockLogProtection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"taxName","type":"string"},{"internalType":"uint256","name":"taxAmount","type":"uint256"}],"name":"setBuyTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setCanAlwaysTrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"bool","name":"isExchange","type":"bool"}],"name":"setExchange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setExcludedFromTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setHighTaxCountdown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setIsSniper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMaxGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMhPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMsPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setNeverSniper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"taxName","type":"string"},{"internalType":"uint256","name":"taxAmount","type":"uint256"}],"name":"setSellTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setSniperBlocking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"uint256","name":"minTime","type":"uint256"}],"name":"setTaxDistributionThresholds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"taxName","type":"string"},{"internalType":"address","name":"wallet","type":"address"}],"name":"setTaxWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sniperTax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"snipersCaught","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxDistributorAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"transactionBlockLog","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"transferTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

60806040526006805460ff191660011790553480156200001e57600080fd5b506040518060400160405280601e81526020017f43656e7472616c2042726f2773204469676974616c2043757272656e63790000815250604051806040016040528060048152602001634342444360e01b8152506200008c620000866200049860201b60201c565b6200049c565b60046200009a838262000dd3565b506005620000a9828262000dd3565b5050506000620000be620004ec60201b60201c565b905060008190506000816001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000106573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200012c919062000e9f565b90506000826001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200016f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000195919062000e9f565b6040516364e329cb60e11b81526001600160a01b038481166004830152306024830152919091169063c9c65396906044016020604051808303816000875af1158015620001e6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020c919062000e9f565b6001600160a01b03811660009081526009602052604090819020805460ff1916600117905551909150849082908490610bb8906101f4906200024e9062000d21565b6001600160a01b03958616815293851660208501529390911660408301526060820152608081019190915260a001604051809103906000f08015801562000299573d6000803e3d6000fd5b50601480546001600160a01b0319166001600160a01b03929092169182179055600a805460ff1990811660019081178355600093845260126020819052604090942080549092161790556064600c55805462ff000019169055601e6015556200030490600a62000fe6565b620003129061271062000ff7565b601655601480546001600160a01b03908116600090815260176020526040808220805460ff1916600117905592549251634693167f60e11b815260a06004820152600960a4820152684d61726b6574696e6760b81b60c48201526101f46024820152610bb8604482015273544d30967e2ecb5305736f5fdcc9c81e811d046a60648201526084810191909152911690638d262cfe9060e401600060405180830381600087803b158015620003c557600080fd5b505af1158015620003da573d6000803e3d6000fd5b50506014805460ff60a01b1981169091556001600160a01b039081166000908152600260209081526040808320938a168352929052206000199055506200042390503362000504565b62000442737a250d5630b4cf539739df2c5dacb4c659f2488d62000556565b6200044d8162000556565b60145462000464906001600160a01b031662000556565b6200048e33620004776012600a62000fe6565b620004889064e8d4a5100062000ff7565b620005da565b50505050620010ba565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b737a250d5630b4cf539739df2c5dacb4c659f2488d90565b601980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fed6cdfec6278ae5a354fde12b296022b0b257f5cb5843a4491932397ef649e4490600090a35050565b6019546001600160a01b03163314620005b65760405162461bcd60e51b815260206004820152601d60248201527f63616c6c6572206973206e6f74207468652063656e7472616c2062726f00000060448201526064015b60405180910390fd5b6001600160a01b03166000908152601c60205260409020805460ff19166001179055565b6001600160a01b038216620006325760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401620005ad565b6200064060008383620006ad565b806003600082825462000654919062001011565b90915550506001600160a01b0382166000818152600160209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0382166000908152601b60205260408120549003620006e9576001600160a01b0382166000908152601b602052604090204390555b620006f6838383620006fb565b505050565b60145460408051630dd8715760e01b815290516000926001600160a01b031691630dd871579160048083019260209291908290030181865afa15801562000746573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200076c919062001027565b62000778904262001041565b600654909150610100900460ff1680156200079c5750601454600160a01b900460ff165b8015620007c157506001600160a01b03831660009081526009602052604090205460ff165b8015620007de575042601854603c620007db919062001011565b11155b8015620007ed57506015548110155b80156200081657506016546014546001600160a01b031660009081526001602052604090205410155b80156200089a5750601460009054906101000a90046001600160a01b03166001600160a01b031663d83067866040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000872573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000898919062001057565b155b15620008ff57426018556014546040805163e4fc6b6d60e01b815290516001600160a01b039092169163e4fc6b6d9160048082019260009290919082900301818387803b158015620008eb57600080fd5b505af1925050508015620008fd575060015b505b6200090c84848462000912565b50505050565b600a5460ff1615806200093557503360009081526011602052604090205460ff16155b620009755760405162461bcd60e51b815260206004820152600f60248201526e1cdb9a5c195c881c995a9958dd1959608a1b6044820152606401620005ad565b600654610100900460ff1680156200099b57506000546001600160a01b03848116911614155b8015620009c157506001600160a01b03831660009081526012602052604090205460ff16155b8015620009e757506001600160a01b03821660009081526012602052604090205460ff16155b1562000ccf57600d541562000a4a57600d545a111562000a4a5760405162461bcd60e51b815260206004820152601e60248201527f74686973206973206f76657220746865206d617820676173206c696d697400006044820152606401620005ad565b6000600c5411801562000a7657506001600160a01b03821660009081526009602052604090205460ff16155b1562000afc5762000a8662000ce2565b6001600160a01b03831660009081526001602052604090205462000aac90839062001011565b111562000afc5760405162461bcd60e51b815260206004820181905260248201527f74686973206973206f76657220746865206d617820686f6c6420616d6f756e746044820152606401620005ad565b6000600b5411801562000b2757506001600160a01b03821660009081526009602052604090205460ff165b1562000b885762000b3762000d0a565b81111562000b885760405162461bcd60e51b815260206004820181905260248201527f74686973206973206f76657220746865206d61782073656c6c20616d6f756e746044820152606401620005ad565b600a54610100900460ff161562000ccf576001600160a01b03821660009081526013602052604090205443900362000bf3576001600160a01b0382166000908152601160205260408120805460ff19166001179055601080549162000bed836200107b565b91905055505b6001600160a01b03831660009081526013602052604090205443900362000c4d576001600160a01b0383166000908152601160205260408120805460ff19166001179055601080549162000c47836200107b565b91905055505b6001600160a01b03821660009081526009602052604081205460ff161515900362000c8e576001600160a01b03821660009081526013602052604090204390555b6001600160a01b03831660009081526009602052604081205460ff161515900362000ccf576001600160a01b03831660009081526013602052604090204390555b620006f68383836001600160e01b038416565b6000612710600c5460035462000cf9919062000ff7565b62000d05919062001097565b905090565b6000612710600b5460035462000cf9919062000ff7565b612b048062003e4d83390190565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168062000d5a57607f821691505b60208210810362000d7b57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620006f657600081815260208120601f850160051c8101602086101562000daa5750805b601f850160051c820191505b8181101562000dcb5782815560010162000db6565b505050505050565b81516001600160401b0381111562000def5762000def62000d2f565b62000e078162000e00845462000d45565b8462000d81565b602080601f83116001811462000e3f576000841562000e265750858301515b600019600386901b1c1916600185901b17855562000dcb565b600085815260208120601f198616915b8281101562000e705788860151825594840194600190910190840162000e4f565b508582101562000e8f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006020828403121562000eb257600080fd5b81516001600160a01b038116811462000eca57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000f2857816000190482111562000f0c5762000f0c62000ed1565b8085161562000f1a57918102915b93841c939080029062000eec565b509250929050565b60008262000f415750600162000fe0565b8162000f505750600062000fe0565b816001811462000f69576002811462000f745762000f94565b600191505062000fe0565b60ff84111562000f885762000f8862000ed1565b50506001821b62000fe0565b5060208310610133831016604e8410600b841016171562000fb9575081810a62000fe0565b62000fc5838362000ee7565b806000190482111562000fdc5762000fdc62000ed1565b0290505b92915050565b600062000eca60ff84168362000f30565b808202811582820484141762000fe05762000fe062000ed1565b8082018082111562000fe05762000fe062000ed1565b6000602082840312156200103a57600080fd5b5051919050565b8181038181111562000fe05762000fe062000ed1565b6000602082840312156200106a57600080fd5b8151801515811462000eca57600080fd5b60006001820162001090576200109062000ed1565b5060010190565b600082620010b557634e487b7160e01b600052601260045260246000fd5b500490565b612d8380620010ca6000396000f3fe608060405234801561001057600080fd5b50600436106104075760003560e01c80636a092e7911610220578063c2ed286b11610130578063dd62ed3e116100b8578063ede49a1911610087578063ede49a19146108db578063f19fffcb146108e8578063f1f5cd91146108fb578063f2fde38b14610903578063f4d1ebe21461091657600080fd5b8063dd62ed3e14610865578063e1cc2b6a1461089e578063e79d4160146108af578063e948474b146108b857600080fd5b8063d00efb2f116100ff578063d00efb2f14610817578063d2d7ad8314610820578063d31acb2814610829578063db38a41d1461083c578063dba61c581461085c57600080fd5b8063c2ed286b146107e0578063c4a5abcd146107f3578063c552f4c5146107fc578063cc1776d31461080f57600080fd5b806381045345116101b3578063a457c2d711610182578063a457c2d714610771578063a9059cbb14610784578063aaf914cb14610797578063b0ad3ebf146107aa578063c20c5caf146107cd57600080fd5b806381045345146107225780638da5cb5b1461073557806395d89b4114610746578063989763ef1461074e57600080fd5b8063715018a6116101ef578063715018a6146106dc5780637412dbb3146106e4578063790ca413146107075780638091f3bf1461071057600080fd5b80636a092e79146106845780636b8f2f3b146106975780636f864552146106ab57806370a08231146106b357600080fd5b8063368274991161031b5780634fbc2775116102ae5780635d90bbaf1161027d5780635d90bbaf1461063a5780635d9d7d431461064d5780635e45da23146106605780636331bf65146106695780636508c57e1461067157600080fd5b80634fbc2775146105ef57806352c6dbc4146106025780635543379a14610614578063583dd79d1461062757600080fd5b80634984a42d116102ea5780634984a42d146105ae5780634e15373e146105c15780634f7041a5146105d45780634f72e2a2146105dc57600080fd5b80633682749914610577578063395093511461058a578063442ef7d21461059d57806345541cba146105a557600080fd5b8063185511081161039e57806323b872dd1161036d57806323b872dd1461050e578063244dafdc1461052157806328be9038146105325780632b75062714610545578063313ce5671461056857600080fd5b806318551108146104bb5780631a00577a146104e05780631f4a6d32146104f3578063233a1d48146104fb57600080fd5b8063095ea7b3116103da578063095ea7b3146104605780630f3a325f146104735780631776834a1461049657806318160ddd146104a957600080fd5b806301339c211461040c578063064a59d01461041657806306fdde031461043857806307a1cfbd1461044d575b600080fd5b610414610929565b005b6006546104239060ff1681565b60405190151581526020015b60405180910390f35b61044061093b565b60405161042f91906128f2565b61041461045b3660046129a8565b6109cd565b61042361046e366004612a09565b610a3d565b610423610481366004612a33565b60116020526000908152604090205460ff1681565b6104146104a4366004612a4e565b610ac9565b6003545b60405190815260200161042f565b6014546001600160a01b03165b6040516001600160a01b03909116815260200161042f565b6104146104ee366004612a33565b610ad6565b610414610b0c565b610423610509366004612a33565b610b63565b61042361051c366004612a67565b610cba565b6019546001600160a01b03166104c8565b610414610540366004612ab1565b610d4b565b610423610553366004612a33565b60126020526000908152604090205460ff1681565b6040516012815260200161042f565b610414610585366004612ae8565b610d7e565b610423610598366004612a09565b610da2565b610414610ef7565b6104ad600b5481565b6104146105bc366004612a33565b610fca565b6104146105cf366004612a33565b611018565b6104ad6110ed565b6104146105ea366004612ae8565b611160565b6104146105fd366004612ab1565b611186565b600a5461042390610100900460ff1681565b610414610622366004612ae8565b6111b9565b610414610635366004612b05565b6111db565b610414610648366004612ab1565b611215565b61041461065b366004612ab1565b611248565b6104ad600d5481565b6104ad61127b565b61041461067f3660046129a8565b61129a565b610423610692366004612b53565b6112d4565b60145461042390600160a01b900460ff1681565b6104ad6113ca565b6104ad6106c1366004612a33565b6001600160a01b031660009081526001602052604090205490565b6104146113df565b6104236106f2366004612a33565b60096020526000908152604090205460ff1681565b6104ad600e5481565b60065461042390610100900460ff1681565b610414610730366004612a4e565b6113f1565b6000546001600160a01b03166104c8565b6104406113fe565b61042361075c366004612a33565b60176020526000908152604090205460ff1681565b61042361077f366004612a09565b61140d565b610423610792366004612a09565b6114fe565b6104ad6107a5366004612a33565b611584565b6104236107b8366004612a33565b60076020526000908152604090205460ff1681565b6104146107db366004612a4e565b6115e3565b6104146107ee366004612ab1565b6115f0565b6104ad600c5481565b61041461080a366004612ae8565b6116a1565b6104ad6116bc565b6104ad600f5481565b6104ad60165481565b610414610837366004612b7d565b611706565b6104ad61084a366004612a33565b60136020526000908152604090205481565b6104ad60155481565b6104ad610873366004612b53565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b601a546001600160a01b03166104c8565b6104ad60105481565b6104236108c6366004612a33565b60086020526000908152604090205460ff1681565b600a546104239060ff1681565b600a546104239062010000900460ff1681565b6104ad611719565b610414610911366004612a33565b61174f565b610414610924366004612a33565b6117c5565b610931611810565b61093961186a565b565b60606004805461094a90612b9f565b80601f016020809104026020016040519081016040528092919081815260200182805461097690612b9f565b80156109c35780601f10610998576101008083540402835291602001916109c3565b820191906000526020600020905b8154815290600101906020018083116109a657829003601f168201915b5050505050905090565b6109d5611810565b6014546040516307a1cfbd60e01b81526001600160a01b03909116906307a1cfbd90610a079085908590600401612bd9565b600060405180830381600087803b158015610a2157600080fd5b505af1158015610a35573d6000803e3d6000fd5b505050505050565b600654600090339060ff168015610a5b5750600654610100900460ff165b80610a7357506000546001600160a01b038281169116145b80610a8d57503360009081526007602052604090205460ff165b610ab25760405162461bcd60e51b8152600401610aa990612bfb565b60405180910390fd5b33610abe818686611884565b506001949350505050565b610ad1611810565b600d55565b6019546001600160a01b03163314610b005760405162461bcd60e51b8152600401610aa990612c28565b610b09816119a8565b50565b610b14611810565b47610b276000546001600160a01b031690565b6001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015610b5f573d6000803e3d6000fd5b5050565b6001600160a01b0381166000908152601c602052604081205460ff1615610b8c57506001919050565b601a546001600160a01b0316610ba457506000919050565b601a546040516370a0823160e01b81526001600160a01b038481166004830152909116906370a0823190602401602060405180830381865afa158015610bee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c129190612c5f565b600003610c2157506000919050565b6001600160a01b0382166000908152601b6020526040902054610c46906137c8612c8e565b601a5460405162a047e360e11b81526001600160a01b038581166004830152909116906301408fc690602401602060405180830381865afa158015610c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb39190612c5f565b1092915050565b6001600160a01b0383166000908152601b60205260408120544390610ce1906137c8612c8e565b1180610cf15750610cf184610b63565b610d385760405162461bcd60e51b815260206004820152601860248201527731b0b73737ba1032b9b1b0b8329032bc3834b930ba34b7b760411b6044820152606401610aa9565b610d438484846119fa565b949350505050565b610d53611810565b6001600160a01b03919091166000908152600960205260409020805460ff1916911515919091179055565b610d86611810565b600a8054911515620100000262ff000019909216919091179055565b600654600090339060ff168015610dc05750600654610100900460ff165b80610dd857506000546001600160a01b038281169116145b80610df257503360009081526007602052604090205460ff165b610e0e5760405162461bcd60e51b8152600401610aa990612bfb565b6001600160a01b038416610e645760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f7420617070726f76652074686520302061646472657373000000006044820152606401610aa9565b3360009081526002602090815260408083206001600160a01b0388168452909152902054610e93908490612c8e565b3360008181526002602090815260408083206001600160a01b038a16808552908352928190208590555193845290927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35060019392505050565b600654610100900460ff16610f605760405162461bcd60e51b815260206004820152602960248201527f63616e206f6e6c792062652063616c6c6564206f6e636520746f6b656e206973604482015268081b185d5b98da195960ba1b6064820152608401610aa9565b601460009054906101000a90046001600160a01b03166001600160a01b031663e4fc6b6d6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610fb057600080fd5b505af1158015610fc4573d6000803e3d6000fd5b50505050565b6019546001600160a01b03163314610ff45760405162461bcd60e51b8152600401610aa990612c28565b6001600160a01b03166000908152601c60205260409020805460ff19166001179055565b6019546001600160a01b031633146110425760405162461bcd60e51b8152600401610aa990612c28565b6001600160a01b03811615158061105d575061105d81611a89565b61109b5760405162461bcd60e51b815260206004820152600f60248201526e696e76616c6964206164647265737360881b6044820152606401610aa9565b601a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f9e33ae69c61f6d4d34940664b1d77e8f52a3de1afef6df98766346c462683f5090600090a35050565b60145460408051631296b91d60e11b815290516000926001600160a01b03169163252d723a9160048083019260209291908290030181865afa158015611137573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115b9190612c5f565b905090565b611168611810565b60148054911515600160a01b0260ff60a01b19909216919091179055565b61118e611810565b6001600160a01b03919091166000908152600760205260409020805460ff1916911515919091179055565b6111c1611810565b600a80549115156101000261ff0019909216919091179055565b6111e3611810565b60145460405163583dd79d60e01b81526001600160a01b039091169063583dd79d90610a079085908590600401612ca1565b61121d611810565b6001600160a01b03919091166000908152601160205260409020805460ff1916911515919091179055565b611250611810565b6001600160a01b03919091166000908152601260205260409020805460ff1916911515919091179055565b6000612710600c546003546112909190612ccb565b61115b9190612ce2565b6112a2611810565b60145460405163328462bf60e11b81526001600160a01b0390911690636508c57e90610a079085908590600401612bd9565b60006112de611810565b6040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa158015611325573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113499190612c5f565b60405163a9059cbb60e01b81526001600160a01b038581166004830152602482018390529192509085169063a9059cbb906044016020604051808303816000875af115801561139c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c09190612d04565b9150505b92915050565b6000612710600b546003546112909190612ccb565b6113e7611810565b6109396000611ac3565b6113f9611810565b600c55565b60606005805461094a90612b9f565b600654600090339060ff16801561142b5750600654610100900460ff165b8061144357506000546001600160a01b038281169116145b8061145d57503360009081526007602052604090205460ff165b6114795760405162461bcd60e51b8152600401610aa990612bfb565b6001600160a01b0384166114cf5760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f7420617070726f76652074686520302061646472657373000000006044820152606401610aa9565b3360009081526002602090815260408083206001600160a01b0388168452909152902054610e93908490612d21565b336000908152601b6020526040812054439061151c906137c8612c8e565b118061152c575061152c33610b63565b6115735760405162461bcd60e51b815260206004820152601860248201527731b0b73737ba1032b9b1b0b8329032bc3834b930ba34b7b760411b6044820152606401610aa9565b61157d8383611b13565b9392505050565b6001600160a01b0381166000908152601b60205260408120548190156115cc576001600160a01b0383166000908152601b60205260409020546115c9906137c8612c8e565b90505b6115d583610b63565b156113c45750600092915050565b6115eb611810565b600b55565b6115f8611810565b6001600160a01b03821660009081526009602052604090205460ff16158061161e575080155b6116765760405162461bcd60e51b815260206004820152602360248201527f43616e6e6f74206578636c75646520616e2065786368616e67652066726f6d206044820152620e8c2f60eb1b6064820152608401610aa9565b6001600160a01b03919091166000908152601760205260409020805460ff1916911515919091179055565b6116a9611810565b600a805460ff1916911515919091179055565b6014546040805163585e42ef60e11b815290516000926001600160a01b03169163b0bc85de9160048083019260209291908290030181865afa158015611137573d6000803e3d6000fd5b61170e611810565b601691909155601555565b600654600090610100900460ff1615611749576003600f544361173c9190612d21565b101561174957506126ac90565b50600090565b611757611810565b6001600160a01b0381166117bc5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610aa9565b610b0981611ac3565b6019546001600160a01b031633146117ef5760405162461bcd60e51b8152600401610aa990612c28565b6001600160a01b03166000908152601c60205260409020805460ff19169055565b6000546001600160a01b031633146109395760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aa9565b611872611810565b61187a611b8b565b42600e5543600f55565b6001600160a01b0383166118e65760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610aa9565b6001600160a01b0382166119475760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610aa9565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b601980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fed6cdfec6278ae5a354fde12b296022b0b257f5cb5843a4491932397ef649e4490600090a35050565b600654600090849060ff168015611a185750600654610100900460ff165b80611a3057506000546001600160a01b038281169116145b80611a4a57503360009081526007602052604090205460ff165b611a665760405162461bcd60e51b8152600401610aa990612bfb565b33611a72868286611ba4565b611a7d868686611c30565b50600195945050505050565b6000611a9d826001600160a01b0316611e61565b611aa957506000919050565b6113c46001600160a01b0383166380ac58cd60e01b611e94565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600654600090339060ff168015611b315750600654610100900460ff165b80611b4957506000546001600160a01b038281169116145b80611b6357503360009081526007602052604090205460ff165b611b7f5760405162461bcd60e51b8152600401610aa990612bfb565b33610abe818686611c30565b611b93611810565b6006805461ff001916610100179055565b6001600160a01b038381166000908152600260209081526040808320938616835292905220546000198114610fc45781811015611c235760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610aa9565b610fc48484848403611884565b6001600160a01b038316611c945760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610aa9565b6001600160a01b038216611cf65760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610aa9565b6001600160a01b03831660009081526008602052604090205460ff1615611d5f5760405162461bcd60e51b815260206004820152601e60248201527f61646472657373206973206e6f7420616c6c6f77656420746f2073656c6c00006044820152606401610aa9565b611d6a838383611eb0565b6000611d77848484611efb565b6001600160a01b03851660009081526001602052604090205490915082811015611df25760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610aa9565b6001600160a01b0380861660008181526001602052604080822087860390559287168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611e529087815260200190565b60405180910390a35050505050565b6000611e74826301ffc9a760e01b611f08565b80156113c45750611e8d826001600160e01b0319611f08565b1592915050565b6000611e9f83611e61565b801561157d575061157d8383611f08565b6001600160a01b0382166000908152601b60205260408120549003611eeb576001600160a01b0382166000908152601b602052604090204390555b611ef6838383611f91565b505050565b6000610d4384848461218d565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d91506000519050828015611f7a575060208210155b8015611f865750600081115b979650505050505050565b60145460408051630dd8715760e01b815290516000926001600160a01b031691630dd871579160048083019260209291908290030181865afa158015611fdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fff9190612c5f565b6120099042612d21565b600654909150610100900460ff16801561202c5750601454600160a01b900460ff165b801561205057506001600160a01b03831660009081526009602052604090205460ff165b801561206a575042601854603c6120679190612c8e565b11155b801561207857506015548110155b80156120a057506016546014546001600160a01b031660009081526001602052604090205410155b80156121205750601460009054906101000a90046001600160a01b03166001600160a01b031663d83067866040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061211e9190612d04565b155b1561218257426018556014546040805163e4fc6b6d60e01b815290516001600160a01b039092169163e4fc6b6d9160048082019260009290919082900301818387803b15801561216f57600080fd5b505af1925050508015612180575060015b505b610fc48484846123c2565b6001600160a01b038316600090815260176020526040812054829060ff161580156121d157506001600160a01b03841660009081526017602052604090205460ff16155b80156121e45750600654610100900460ff165b15612313576001600160a01b03851660009081526009602052604090205460ff16156122805760145460405163db017dc760e01b8152600481018590526001600160a01b039091169063db017dc7906024016020604051808303816000875af1158015612255573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122799190612c5f565b9050612313565b6001600160a01b03841660009081526009602052604090205460ff161561231357601454604051634fa26fd560e01b8152600481018590526001600160a01b0390911690634fa26fd5906024016020604051808303816000875af11580156122ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123109190612c5f565b90505b600061231f8285612d21565b905080156123ad576014546001600160a01b031660009081526001602052604090205461234d908290612c8e565b601480546001600160a01b03908116600090815260016020908152604091829020949094559154915184815291811692908916917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b6123b8868684612760565b9695505050505050565b600a5460ff1615806123e457503360009081526011602052604090205460ff16155b6124225760405162461bcd60e51b815260206004820152600f60248201526e1cdb9a5c195c881c995a9958dd1959608a1b6044820152606401610aa9565b600654610100900460ff16801561244757506000546001600160a01b03848116911614155b801561246c57506001600160a01b03831660009081526012602052604090205460ff16155b801561249157506001600160a01b03821660009081526012602052604090205460ff16155b15611ef657600d54156124f057600d545a11156124f05760405162461bcd60e51b815260206004820152601e60248201527f74686973206973206f76657220746865206d617820676173206c696d697400006044820152606401610aa9565b6000600c5411801561251b57506001600160a01b03821660009081526009602052604090205460ff16155b1561259a5761252861127b565b6001600160a01b03831660009081526001602052604090205461254c908390612c8e565b111561259a5760405162461bcd60e51b815260206004820181905260248201527f74686973206973206f76657220746865206d617820686f6c6420616d6f756e746044820152606401610aa9565b6000600b541180156125c457506001600160a01b03821660009081526009602052604090205460ff165b15612620576125d16113ca565b8111156126205760405162461bcd60e51b815260206004820181905260248201527f74686973206973206f76657220746865206d61782073656c6c20616d6f756e746044820152606401610aa9565b600a54610100900460ff1615611ef6576001600160a01b038216600090815260136020526040902054439003612687576001600160a01b0382166000908152601160205260408120805460ff19166001179055601080549161268183612d34565b91905055505b6001600160a01b0383166000908152601360205260409020544390036126de576001600160a01b0383166000908152601160205260408120805460ff1916600117905560108054916126d883612d34565b91905055505b6001600160a01b03821660009081526009602052604081205460ff161515900361271e576001600160a01b03821660009081526013602052604090204390555b6001600160a01b03831660009081526009602052604081205460ff1615159003611ef65750506001600160a01b03166000908152601360205260409020439055565b6006546000908290610100900460ff1680156127845750600a5462010000900460ff165b1561282e576000546001600160a01b038681169116148015906127ae575060006127ac611719565b115b80156127d357506001600160a01b03851660009081526012602052604090205460ff16155b80156127f857506001600160a01b03841660009081526012602052604090205460ff16155b1561282e57600061271061280a611719565b6128149086612ccb565b61281e9190612ce2565b905061282a8183612d21565b9150505b612839858583612842565b95945050505050565b6000826001600160a01b0316846001600160a01b0316036128a55760405162461bcd60e51b815260206004820152601f60248201527f796f752063616e6e6f74207472616e7366657220746f20796f757273656c66006044820152606401610aa9565b5092915050565b6000815180845260005b818110156128d2576020818501810151868301820152016128b6565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061157d60208301846128ac565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261292c57600080fd5b813567ffffffffffffffff8082111561294757612947612905565b604051601f8301601f19908116603f0116810190828211818310171561296f5761296f612905565b8160405283815286602085880101111561298857600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080604083850312156129bb57600080fd5b823567ffffffffffffffff8111156129d257600080fd5b6129de8582860161291b565b95602094909401359450505050565b80356001600160a01b0381168114612a0457600080fd5b919050565b60008060408385031215612a1c57600080fd5b612a25836129ed565b946020939093013593505050565b600060208284031215612a4557600080fd5b61157d826129ed565b600060208284031215612a6057600080fd5b5035919050565b600080600060608486031215612a7c57600080fd5b612a85846129ed565b9250612a93602085016129ed565b9150604084013590509250925092565b8015158114610b0957600080fd5b60008060408385031215612ac457600080fd5b612acd836129ed565b91506020830135612add81612aa3565b809150509250929050565b600060208284031215612afa57600080fd5b813561157d81612aa3565b60008060408385031215612b1857600080fd5b823567ffffffffffffffff811115612b2f57600080fd5b612b3b8582860161291b565b925050612b4a602084016129ed565b90509250929050565b60008060408385031215612b6657600080fd5b612b6f836129ed565b9150612b4a602084016129ed565b60008060408385031215612b9057600080fd5b50508035926020909101359150565b600181811c90821680612bb357607f821691505b602082108103612bd357634e487b7160e01b600052602260045260246000fd5b50919050565b604081526000612bec60408301856128ac565b90508260208301529392505050565b6020808252601390820152721d1c98591a5b99c81b9bdd08195b98589b1959606a1b604082015260600190565b6020808252601d908201527f63616c6c6572206973206e6f74207468652063656e7472616c2062726f000000604082015260600190565b600060208284031215612c7157600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156113c4576113c4612c78565b604081526000612cb460408301856128ac565b905060018060a01b03831660208301529392505050565b80820281158282048414176113c4576113c4612c78565b600082612cff57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215612d1657600080fd5b815161157d81612aa3565b818103818111156113c4576113c4612c78565b600060018201612d4657612d46612c78565b506001019056fea26469706673582212205f0fe7ab24be5133a4a3270b14893519465468ad7745de0daa90049e1cec551064736f6c634300081300336101406040523480156200001257600080fd5b5060405162002b0438038062002b0483398101604081905262000035916200019e565b6001600160a01b038316620000915760405162461bcd60e51b815260206004820152601f60248201527f706169726564546f6b656e2063616e6e6f74206265203020616464726573730060448201526064015b60405180910390fd5b6001600160a01b038416620000e95760405162461bcd60e51b815260206004820152601860248201527f706169722063616e6e6f74206265203020616464726573730000000000000000604482015260640162000088565b6001600160a01b038516620001415760405162461bcd60e51b815260206004820152601a60248201527f726f757465722063616e6e6f7420626520302061646472657373000000000000604482015260640162000088565b3360c0526001600160a01b0392831660e052600080546001600160a01b031916958416958617905561010091909152610120521660805260a052620001fb565b80516001600160a01b03811681146200019957600080fd5b919050565b600080600080600060a08688031215620001b757600080fd5b620001c28662000181565b9450620001d26020870162000181565b9350620001e26040870162000181565b6060870151608090970151959894975095949392505050565b60805160a05160c05160e0516101005161012051612842620002c26000396000818161031f01526105680152600081816102a20152610ba80152600061101c0152600081816103f9015281816105ed015281816107630152818161080301528181610887015281816109ae01528181610ae201528181610bda01528181610c5e01528181610dec01528181610f0901528181610fc80152818161106a015281816119aa01528181611cec0152611ea9015260006101d6015260006103cc01526128426000f3fe6080604052600436106101185760003560e01c80638d262cfe116100a0578063d830678611610064578063d830678614610341578063db017dc714610372578063e4fc6b6d14610392578063ed4ce99e1461039a578063ee16c160146103ba57600080fd5b80638d262cfe14610270578063a411209a14610290578063b0bc85de146102c4578063c5be2bc7146102d9578063c8e956ab1461030d57600080fd5b80632b1fb89e116100e75780632b1fb89e146101a45780633268cc56146101c45780634fa26fd514610210578063583dd79d146102305780636508c57e1461025057600080fd5b806307a1cfbd146101245780630dd8715714610146578063135b4fc01461016f578063252d723a1461018f57600080fd5b3661011f57005b600080fd5b34801561013057600080fd5b5061014461013f3660046121a6565b6103ee565b005b34801561015257600080fd5b5061015c60015481565b6040519081526020015b60405180910390f35b34801561017b57600080fd5b5061014461018a366004612213565b6105e2565b34801561019b57600080fd5b5061015c610756565b3480156101b057600080fd5b506101446101bf366004612213565b6107f8565b3480156101d057600080fd5b506101f87f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610166565b34801561021c57600080fd5b5061015c61022b366004612289565b61087a565b34801561023c57600080fd5b5061014461024b3660046122a2565b6109a3565b34801561025c57600080fd5b5061014461026b3660046121a6565b610ad7565b34801561027c57600080fd5b5061014461028b366004612213565b610bcf565b34801561029c57600080fd5b5061015c7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102d057600080fd5b5061015c610c51565b3480156102e557600080fd5b506102f96102f4366004612289565b610ced565b60405161016698979695949392919061232a565b34801561031957600080fd5b5061015c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561034d57600080fd5b5060005461036290600160a01b900460ff1681565b6040519015158152602001610166565b34801561037e57600080fd5b5061015c61038d366004612289565b610ddf565b610144610efe565b3480156103a657600080fd5b506101446103b53660046123c9565b611e9e565b3480156103c657600080fd5b506101f87f000000000000000000000000000000000000000000000000000000000000000081565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461043f5760405162461bcd60e51b81526004016104369061242a565b60405180910390fd5b6000805b600254811015610548576105036002828154811061046357610463612452565b9060005260206000209060070201600001805461047f90612468565b80601f01602080910402602001604051908101604052809291908181526020018280546104ab90612468565b80156104f85780601f106104cd576101008083540402835291602001916104f8565b820191906000526020600020905b8154815290600101906020018083116104db57829003601f168201915b50505050508561200e565b1561053657826002828154811061051c5761051c612452565b906000526020600020906007020160010181905550600191505b80610540816124b8565b915050610443565b50806105665760405162461bcd60e51b8152600401610436906124d1565b7f000000000000000000000000000000000000000000000000000000000000000061058f610756565b11156105dd5760405162461bcd60e51b815260206004820152601b60248201527f7461782063616e6e6f74206265207365742074686973206869676800000000006044820152606401610436565b505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461062a5760405162461bcd60e51b81526004016104369061242a565b60026040518061010001604052808781526020018681526020018581526020016000815260200160038081111561066357610663612314565b81526001600160a01b0385166020808301919091526000604083018190528515156060909301929092528354600181018555938252902081519192600702019081906106af9082612556565b5060208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a81548160ff021916908360038111156106f8576106f8612314565b021790555060a0820151600482018054610100600160a81b0319166101006001600160a01b039093169290920291909117905560c0820151600582015560e0909101516006909101805460ff19169115159190911790555050505050565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107a05760405162461bcd60e51b81526004016104369061242a565b6000805b6002548110156107f257600281815481106107c1576107c1612452565b906000526020600020906007020160010154826107de9190612616565b9150806107ea816124b8565b9150506107a4565b50905090565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108405760405162461bcd60e51b81526004016104369061242a565b6002604051806101000160405280878152602001868152602001858152602001600081526020016001600381111561066357610663612314565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108c45760405162461bcd60e51b81526004016104369061242a565b60005b600254811015610999576000600282815481106108e6576108e6612452565b90600052602060002090600702016002015411156109875760006127106002838154811061091657610916612452565b906000526020600020906007020160020154856109339190612629565b61093d9190612640565b9050806002838154811061095357610953612452565b906000526020600020906007020160030160008282546109739190612616565b9091555061098390508185612662565b9350505b80610991816124b8565b9150506108c7565b508190505b919050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109eb5760405162461bcd60e51b81526004016104369061242a565b6000805b600254811015610ab957600060028281548110610a0e57610a0e612452565b600091825260209091206004600790920201015460ff166003811115610a3657610a36612314565b148015610a545750610a546002828154811061046357610463612452565b15610aa7578260028281548110610a6d57610a6d612452565b906000526020600020906007020160040160016101000a8154816001600160a01b0302191690836001600160a01b03160217905550600191505b80610ab1816124b8565b9150506109ef565b50806105dd5760405162461bcd60e51b8152600401610436906124d1565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b1f5760405162461bcd60e51b81526004016104369061242a565b6000805b600254811015610b8857610b436002828154811061046357610463612452565b15610b76578260028281548110610b5c57610b5c612452565b906000526020600020906007020160020181905550600191505b80610b80816124b8565b915050610b23565b5080610ba65760405162461bcd60e51b8152600401610436906124d1565b7f000000000000000000000000000000000000000000000000000000000000000061058f610c51565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c175760405162461bcd60e51b81526004016104369061242a565b6002604051806101000160405280878152602001868152602001858152602001600081526020016000600381111561066357610663612314565b6000336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c9b5760405162461bcd60e51b81526004016104369061242a565b6000805b6002548110156107f25760028181548110610cbc57610cbc612452565b90600052602060002090600702016002015482610cd99190612616565b915080610ce5816124b8565b915050610c9f565b60028181548110610cfd57600080fd5b9060005260206000209060070201600091509050806000018054610d2090612468565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4c90612468565b8015610d995780601f10610d6e57610100808354040283529160200191610d99565b820191906000526020600020905b815481529060010190602001808311610d7c57829003601f168201915b505050506001830154600284015460038501546004860154600587015460069097015495969395929450909260ff808316936101009093046001600160a01b0316921688565b6000336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610e295760405162461bcd60e51b81526004016104369061242a565b60005b60025481101561099957600060028281548110610e4b57610e4b612452565b9060005260206000209060070201600101541115610eec57600061271060028381548110610e7b57610e7b612452565b90600052602060002090600702016001015485610e989190612629565b610ea29190612640565b90508060028381548110610eb857610eb8612452565b90600052602060002090600702016003016000828254610ed89190612616565b90915550610ee890508185612662565b9350505b80610ef6816124b8565b915050610e2c565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610f465760405162461bcd60e51b81526004016104369061242a565b600054600160a01b900460ff1615610f935760405162461bcd60e51b815260206004820152601060248201526f616c7265616479207377617070696e6760801b6044820152606401610436565b6000805460ff60a01b1916600160a01b17815560408051600280825260608201835290916020830190803683370190505090507f000000000000000000000000000000000000000000000000000000000000000081600081518110610ffa57610ffa612452565b60200260200101906001600160a01b031690816001600160a01b0316815250507f00000000000000000000000000000000000000000000000000000000000000008160018151811061104e5761104e612452565b6001600160a01b039092166020928302919091019091015260007f000000000000000000000000000000000000000000000000000000000000000081805b6002548110156111c15760028082815481106110aa576110aa612452565b600091825260209091206004600790920201015460ff1660038111156110d2576110d2612314565b0361114d57600060028083815481106110ed576110ed612452565b9060005260206000209060070201600301546111099190612640565b9050806002838154811061111f5761111f612452565b90600052602060002090600702016003015461113b9190612662565b6111459084612616565b9250506111af565b6002818154811061116057611160612452565b600091825260209091206006600790920201015460ff16156111af576002818154811061118f5761118f612452565b906000526020600020906007020160030154826111ac9190612616565b91505b806111b9816124b8565b91505061108c565b506111cc8282612068565b9050806111d98383612068565b1461126a577fde3142f93c040ab4be0d03a16ac06c502816c1205865dd41d9848727102570d16040516112599060208082526033908201527f496e73756666696369656e7420746f6b656e7320746f20737761702e20506c6560408201527261736520616464206d6f726520746f6b656e7360681b606082015260800190565b60405180910390a150505050611e8f565b801561160457600080546001600160a01b03166318cbafe5838388306112924261012c612616565b6040518663ffffffff1660e01b81526004016112b2959493929190612675565b6000604051808303816000875af11580156112d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112f991908101906126e6565b90504793508060008151811061131157611311612452565b60200260200101518214158061134157508060018151811061133557611335612452565b60200260200101518414155b156113bc577fde3142f93c040ab4be0d03a16ac06c502816c1205865dd41d9848727102570d16040516113b39060208082526025908201527f556e657870656374656420616d6f756e74732072657475726e65642066726f6d604082015264020737761760dc1b606082015260800190565b60405180910390a15b8360005b60025481101561160057600281815481106113dd576113dd612452565b600091825260209091206006600790920201015460ff16806114385750600280828154811061140e5761140e612452565b600091825260209091206004600790920201015460ff16600381111561143657611436612314565b145b156115ee5760025461144c90600190612662565b810361148057816002828154811061146657611466612452565b9060005260206000209060070201600501819055506115ee565b600280828154811061149457611494612452565b600091825260209091206004600790920201015460ff1660038111156114bc576114bc612314565b0361157957600060028083815481106114d7576114d7612452565b9060005260206000209060070201600301546114f39190612640565b9050600085826002858154811061150c5761150c612452565b9060005260206000209060070201600301546115289190612662565b611532908a612629565b61153c9190612640565b9050806002848154811061155257611552612452565b60009182526020909120600560079092020101556115708185612662565b935050506115ee565b6000846002838154811061158f5761158f612452565b906000526020600020906007020160030154886115ac9190612629565b6115b69190612640565b905080600283815481106115cc576115cc612452565b60009182526020909120600560079092020101556115ea8184612662565b9250505b806115f8816124b8565b9150506113c0565b5050505b60005b600254811015611e4c5760006002828154811061162657611626612452565b600091825260209091206004600790920201015460ff16600381111561164e5761164e612314565b03611800576002818154811061166657611666612452565b600091825260209091206006600790920201015460ff161561171c576002818154811061169557611695612452565b906000526020600020906007020160040160019054906101000a90046001600160a01b03166001600160a01b03166108fc600283815481106116d9576116d9612452565b9060005260206000209060070201600501549081150290604051600060405180830381858888f19350505050158015611716573d6000803e3d6000fd5b50611de7565b826001600160a01b031663a9059cbb6002838154811061173e5761173e612452565b906000526020600020906007020160040160019054906101000a90046001600160a01b0316611791866002868154811061177a5761177a612452565b906000526020600020906007020160030154612068565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156117dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611716919061278c565b60036002828154811061181557611815612452565b600091825260209091206004600790920201015460ff16600381111561183d5761183d612314565b03611a4e576002818154811061185557611855612452565b600091825260209091206006600790920201015460ff1615611884576002818154811061169557611695612452565b826001600160a01b031663095ea7b3600283815481106118a6576118a6612452565b906000526020600020906007020160040160019054906101000a90046001600160a01b0316600284815481106118de576118de612452565b60009182526020909120600360079092020101546040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af115801561193d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611961919061278c565b506002818154811061197557611975612452565b906000526020600020906007020160040160019054906101000a90046001600160a01b03166001600160a01b0316634ec109f47f0000000000000000000000000000000000000000000000000000000000000000306119e1876002878154811061177a5761177a612452565b6040516001600160e01b031960e086901b1681526001600160a01b03938416600482015292909116602483015260448201526064015b600060405180830381600087803b158015611a3157600080fd5b505af1158015611a45573d6000803e3d6000fd5b50505050611de7565b600160028281548110611a6357611a63612452565b600091825260209091206004600790920201015460ff166003811115611a8b57611a8b612314565b03611c025760028181548110611aa357611aa3612452565b600091825260209091206006600790920201015460ff1615611b735760028181548110611ad257611ad2612452565b906000526020600020906007020160040160019054906101000a90046001600160a01b03166001600160a01b031663db6b524660028381548110611b1857611b18612452565b9060005260206000209060070201600501546040518263ffffffff1660e01b81526004016000604051808303818588803b158015611b5557600080fd5b505af1158015611b69573d6000803e3d6000fd5b5050505050611de7565b60028181548110611b8657611b86612452565b906000526020600020906007020160040160019054906101000a90046001600160a01b03166001600160a01b031663338b5dea30611bd1866002868154811061177a5761177a612452565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401611a17565b6002808281548110611c1657611c16612452565b600091825260209091206004600790920201015460ff166003811115611c3e57611c3e612314565b03611de757600060028281548110611c5857611c58612452565b9060005260206000209060070201600501541115611de7576000611cab846002808581548110611c8a57611c8a612452565b906000526020600020906007020160030154611ca69190612640565b612068565b600054600280549293506001600160a01b039091169163f305d719919085908110611cd857611cd8612452565b9060005260206000209060070201600501547f00000000000000000000000000000000000000000000000000000000000000008460008060028981548110611d2257611d22612452565b600091825260209091206007909102016004015461010090046001600160a01b0316611d504261012c612616565b60405160e089901b6001600160e01b03191681526001600160a01b039687166004820152602481019590955260448501939093526064840191909152909216608482015260a481019190915260c40160606040518083038185885af1158015611dbd573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611de291906127a9565b505050505b600060028281548110611dfc57611dfc612452565b906000526020600020906007020160030181905550600060028281548110611e2657611e26612452565b600091825260209091206005600790920201015580611e44816124b8565b915050611607565b5060408051828152602081018590527f5e20c9aee521e656eed033c4ae35378c79c584706f5ce7f410ab3fba389607a1910160405180910390a150504260015550505b6000805460ff60a01b19169055565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611ee65760405162461bcd60e51b81526004016104369061242a565b60026040518061010001604052808681526020018581526020018481526020016000815260200160026003811115611f2057611f20612314565b81526001600160a01b0384166020808301919091526000604083018190526060909201829052835460018101855593825290208151919260070201908190611f689082612556565b5060208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a81548160ff02191690836003811115611fb157611fb1612314565b021790555060a0820151600482018054610100600160a81b0319166101006001600160a01b039093169290920291909117905560c0820151600582015560e0909101516006909101805460ff191691151591909117905550505050565b60008160405160200161202191906127d7565b604051602081830303815290604052805190602001208360405160200161204891906127d7565b604051602081830303815290604052805190602001201490505b92915050565b6040516370a0823160e01b815230600482015260009081906001600160a01b038516906370a0823190602401602060405180830381865afa1580156120b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d591906127f3565b9050828111156120e85782915050612062565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561212e5761212e6120ef565b604052919050565b600082601f83011261214757600080fd5b813567ffffffffffffffff811115612161576121616120ef565b612174601f8201601f1916602001612105565b81815284602083860101111561218957600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156121b957600080fd5b823567ffffffffffffffff8111156121d057600080fd5b6121dc85828601612136565b95602094909401359450505050565b80356001600160a01b038116811461099e57600080fd5b801515811461221057600080fd5b50565b600080600080600060a0868803121561222b57600080fd5b853567ffffffffffffffff81111561224257600080fd5b61224e88828901612136565b955050602086013593506040860135925061226b606087016121eb565b9150608086013561227b81612202565b809150509295509295909350565b60006020828403121561229b57600080fd5b5035919050565b600080604083850312156122b557600080fd5b823567ffffffffffffffff8111156122cc57600080fd5b6122d885828601612136565b9250506122e7602084016121eb565b90509250929050565b60005b8381101561230b5781810151838201526020016122f3565b50506000910152565b634e487b7160e01b600052602160045260246000fd5b60006101008083528a518082850152610120915061234e8183860160208f016122f0565b602084018b9052604084018a905260608401899052601f01601f191683010190506004861061238d57634e487b7160e01b600052602160045260246000fd5b8560808301526123a860a08301866001600160a01b03169052565b8360c08301526123bc60e083018415159052565b9998505050505050505050565b600080600080608085870312156123df57600080fd5b843567ffffffffffffffff8111156123f657600080fd5b61240287828801612136565b945050602085013592506040850135915061241f606086016121eb565b905092959194509250565b6020808252600e908201526d6e6f207065726d697373696f6e7360901b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061247c57607f821691505b60208210810361249c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6000600182016124ca576124ca6124a2565b5060010190565b6020808252601c908201527f636f756c64206e6f742066696e642074617820746f2075706461746500000000604082015260600190565b601f8211156105dd57600081815260208120601f850160051c8101602086101561252f5750805b601f850160051c820191505b8181101561254e5782815560010161253b565b505050505050565b815167ffffffffffffffff811115612570576125706120ef565b6125848161257e8454612468565b84612508565b602080601f8311600181146125b957600084156125a15750858301515b600019600386901b1c1916600185901b17855561254e565b600085815260208120601f198616915b828110156125e8578886015182559484019460019091019084016125c9565b50858210156126065787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b80820180821115612062576120626124a2565b8082028115828204841417612062576120626124a2565b60008261265d57634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115612062576120626124a2565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156126c55784516001600160a01b0316835293830193918301916001016126a0565b50506001600160a01b03969096166060850152505050608001529392505050565b600060208083850312156126f957600080fd5b825167ffffffffffffffff8082111561271157600080fd5b818501915085601f83011261272557600080fd5b815181811115612737576127376120ef565b8060051b9150612748848301612105565b818152918301840191848101908884111561276257600080fd5b938501935b8385101561278057845182529385019390850190612767565b98975050505050505050565b60006020828403121561279e57600080fd5b81516120e881612202565b6000806000606084860312156127be57600080fd5b8351925060208401519150604084015190509250925092565b600082516127e98184602087016122f0565b9190910192915050565b60006020828403121561280557600080fd5b505191905056fea2646970667358221220224e5374ffeeb74b8d3396ebaf5487ca294e7f6e9f8dd19abd4628218e266db364736f6c63430008130033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106104075760003560e01c80636a092e7911610220578063c2ed286b11610130578063dd62ed3e116100b8578063ede49a1911610087578063ede49a19146108db578063f19fffcb146108e8578063f1f5cd91146108fb578063f2fde38b14610903578063f4d1ebe21461091657600080fd5b8063dd62ed3e14610865578063e1cc2b6a1461089e578063e79d4160146108af578063e948474b146108b857600080fd5b8063d00efb2f116100ff578063d00efb2f14610817578063d2d7ad8314610820578063d31acb2814610829578063db38a41d1461083c578063dba61c581461085c57600080fd5b8063c2ed286b146107e0578063c4a5abcd146107f3578063c552f4c5146107fc578063cc1776d31461080f57600080fd5b806381045345116101b3578063a457c2d711610182578063a457c2d714610771578063a9059cbb14610784578063aaf914cb14610797578063b0ad3ebf146107aa578063c20c5caf146107cd57600080fd5b806381045345146107225780638da5cb5b1461073557806395d89b4114610746578063989763ef1461074e57600080fd5b8063715018a6116101ef578063715018a6146106dc5780637412dbb3146106e4578063790ca413146107075780638091f3bf1461071057600080fd5b80636a092e79146106845780636b8f2f3b146106975780636f864552146106ab57806370a08231146106b357600080fd5b8063368274991161031b5780634fbc2775116102ae5780635d90bbaf1161027d5780635d90bbaf1461063a5780635d9d7d431461064d5780635e45da23146106605780636331bf65146106695780636508c57e1461067157600080fd5b80634fbc2775146105ef57806352c6dbc4146106025780635543379a14610614578063583dd79d1461062757600080fd5b80634984a42d116102ea5780634984a42d146105ae5780634e15373e146105c15780634f7041a5146105d45780634f72e2a2146105dc57600080fd5b80633682749914610577578063395093511461058a578063442ef7d21461059d57806345541cba146105a557600080fd5b8063185511081161039e57806323b872dd1161036d57806323b872dd1461050e578063244dafdc1461052157806328be9038146105325780632b75062714610545578063313ce5671461056857600080fd5b806318551108146104bb5780631a00577a146104e05780631f4a6d32146104f3578063233a1d48146104fb57600080fd5b8063095ea7b3116103da578063095ea7b3146104605780630f3a325f146104735780631776834a1461049657806318160ddd146104a957600080fd5b806301339c211461040c578063064a59d01461041657806306fdde031461043857806307a1cfbd1461044d575b600080fd5b610414610929565b005b6006546104239060ff1681565b60405190151581526020015b60405180910390f35b61044061093b565b60405161042f91906128f2565b61041461045b3660046129a8565b6109cd565b61042361046e366004612a09565b610a3d565b610423610481366004612a33565b60116020526000908152604090205460ff1681565b6104146104a4366004612a4e565b610ac9565b6003545b60405190815260200161042f565b6014546001600160a01b03165b6040516001600160a01b03909116815260200161042f565b6104146104ee366004612a33565b610ad6565b610414610b0c565b610423610509366004612a33565b610b63565b61042361051c366004612a67565b610cba565b6019546001600160a01b03166104c8565b610414610540366004612ab1565b610d4b565b610423610553366004612a33565b60126020526000908152604090205460ff1681565b6040516012815260200161042f565b610414610585366004612ae8565b610d7e565b610423610598366004612a09565b610da2565b610414610ef7565b6104ad600b5481565b6104146105bc366004612a33565b610fca565b6104146105cf366004612a33565b611018565b6104ad6110ed565b6104146105ea366004612ae8565b611160565b6104146105fd366004612ab1565b611186565b600a5461042390610100900460ff1681565b610414610622366004612ae8565b6111b9565b610414610635366004612b05565b6111db565b610414610648366004612ab1565b611215565b61041461065b366004612ab1565b611248565b6104ad600d5481565b6104ad61127b565b61041461067f3660046129a8565b61129a565b610423610692366004612b53565b6112d4565b60145461042390600160a01b900460ff1681565b6104ad6113ca565b6104ad6106c1366004612a33565b6001600160a01b031660009081526001602052604090205490565b6104146113df565b6104236106f2366004612a33565b60096020526000908152604090205460ff1681565b6104ad600e5481565b60065461042390610100900460ff1681565b610414610730366004612a4e565b6113f1565b6000546001600160a01b03166104c8565b6104406113fe565b61042361075c366004612a33565b60176020526000908152604090205460ff1681565b61042361077f366004612a09565b61140d565b610423610792366004612a09565b6114fe565b6104ad6107a5366004612a33565b611584565b6104236107b8366004612a33565b60076020526000908152604090205460ff1681565b6104146107db366004612a4e565b6115e3565b6104146107ee366004612ab1565b6115f0565b6104ad600c5481565b61041461080a366004612ae8565b6116a1565b6104ad6116bc565b6104ad600f5481565b6104ad60165481565b610414610837366004612b7d565b611706565b6104ad61084a366004612a33565b60136020526000908152604090205481565b6104ad60155481565b6104ad610873366004612b53565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b601a546001600160a01b03166104c8565b6104ad60105481565b6104236108c6366004612a33565b60086020526000908152604090205460ff1681565b600a546104239060ff1681565b600a546104239062010000900460ff1681565b6104ad611719565b610414610911366004612a33565b61174f565b610414610924366004612a33565b6117c5565b610931611810565b61093961186a565b565b60606004805461094a90612b9f565b80601f016020809104026020016040519081016040528092919081815260200182805461097690612b9f565b80156109c35780601f10610998576101008083540402835291602001916109c3565b820191906000526020600020905b8154815290600101906020018083116109a657829003601f168201915b5050505050905090565b6109d5611810565b6014546040516307a1cfbd60e01b81526001600160a01b03909116906307a1cfbd90610a079085908590600401612bd9565b600060405180830381600087803b158015610a2157600080fd5b505af1158015610a35573d6000803e3d6000fd5b505050505050565b600654600090339060ff168015610a5b5750600654610100900460ff165b80610a7357506000546001600160a01b038281169116145b80610a8d57503360009081526007602052604090205460ff165b610ab25760405162461bcd60e51b8152600401610aa990612bfb565b60405180910390fd5b33610abe818686611884565b506001949350505050565b610ad1611810565b600d55565b6019546001600160a01b03163314610b005760405162461bcd60e51b8152600401610aa990612c28565b610b09816119a8565b50565b610b14611810565b47610b276000546001600160a01b031690565b6001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015610b5f573d6000803e3d6000fd5b5050565b6001600160a01b0381166000908152601c602052604081205460ff1615610b8c57506001919050565b601a546001600160a01b0316610ba457506000919050565b601a546040516370a0823160e01b81526001600160a01b038481166004830152909116906370a0823190602401602060405180830381865afa158015610bee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c129190612c5f565b600003610c2157506000919050565b6001600160a01b0382166000908152601b6020526040902054610c46906137c8612c8e565b601a5460405162a047e360e11b81526001600160a01b038581166004830152909116906301408fc690602401602060405180830381865afa158015610c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb39190612c5f565b1092915050565b6001600160a01b0383166000908152601b60205260408120544390610ce1906137c8612c8e565b1180610cf15750610cf184610b63565b610d385760405162461bcd60e51b815260206004820152601860248201527731b0b73737ba1032b9b1b0b8329032bc3834b930ba34b7b760411b6044820152606401610aa9565b610d438484846119fa565b949350505050565b610d53611810565b6001600160a01b03919091166000908152600960205260409020805460ff1916911515919091179055565b610d86611810565b600a8054911515620100000262ff000019909216919091179055565b600654600090339060ff168015610dc05750600654610100900460ff165b80610dd857506000546001600160a01b038281169116145b80610df257503360009081526007602052604090205460ff165b610e0e5760405162461bcd60e51b8152600401610aa990612bfb565b6001600160a01b038416610e645760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f7420617070726f76652074686520302061646472657373000000006044820152606401610aa9565b3360009081526002602090815260408083206001600160a01b0388168452909152902054610e93908490612c8e565b3360008181526002602090815260408083206001600160a01b038a16808552908352928190208590555193845290927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35060019392505050565b600654610100900460ff16610f605760405162461bcd60e51b815260206004820152602960248201527f63616e206f6e6c792062652063616c6c6564206f6e636520746f6b656e206973604482015268081b185d5b98da195960ba1b6064820152608401610aa9565b601460009054906101000a90046001600160a01b03166001600160a01b031663e4fc6b6d6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610fb057600080fd5b505af1158015610fc4573d6000803e3d6000fd5b50505050565b6019546001600160a01b03163314610ff45760405162461bcd60e51b8152600401610aa990612c28565b6001600160a01b03166000908152601c60205260409020805460ff19166001179055565b6019546001600160a01b031633146110425760405162461bcd60e51b8152600401610aa990612c28565b6001600160a01b03811615158061105d575061105d81611a89565b61109b5760405162461bcd60e51b815260206004820152600f60248201526e696e76616c6964206164647265737360881b6044820152606401610aa9565b601a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f9e33ae69c61f6d4d34940664b1d77e8f52a3de1afef6df98766346c462683f5090600090a35050565b60145460408051631296b91d60e11b815290516000926001600160a01b03169163252d723a9160048083019260209291908290030181865afa158015611137573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115b9190612c5f565b905090565b611168611810565b60148054911515600160a01b0260ff60a01b19909216919091179055565b61118e611810565b6001600160a01b03919091166000908152600760205260409020805460ff1916911515919091179055565b6111c1611810565b600a80549115156101000261ff0019909216919091179055565b6111e3611810565b60145460405163583dd79d60e01b81526001600160a01b039091169063583dd79d90610a079085908590600401612ca1565b61121d611810565b6001600160a01b03919091166000908152601160205260409020805460ff1916911515919091179055565b611250611810565b6001600160a01b03919091166000908152601260205260409020805460ff1916911515919091179055565b6000612710600c546003546112909190612ccb565b61115b9190612ce2565b6112a2611810565b60145460405163328462bf60e11b81526001600160a01b0390911690636508c57e90610a079085908590600401612bd9565b60006112de611810565b6040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa158015611325573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113499190612c5f565b60405163a9059cbb60e01b81526001600160a01b038581166004830152602482018390529192509085169063a9059cbb906044016020604051808303816000875af115801561139c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c09190612d04565b9150505b92915050565b6000612710600b546003546112909190612ccb565b6113e7611810565b6109396000611ac3565b6113f9611810565b600c55565b60606005805461094a90612b9f565b600654600090339060ff16801561142b5750600654610100900460ff165b8061144357506000546001600160a01b038281169116145b8061145d57503360009081526007602052604090205460ff165b6114795760405162461bcd60e51b8152600401610aa990612bfb565b6001600160a01b0384166114cf5760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f7420617070726f76652074686520302061646472657373000000006044820152606401610aa9565b3360009081526002602090815260408083206001600160a01b0388168452909152902054610e93908490612d21565b336000908152601b6020526040812054439061151c906137c8612c8e565b118061152c575061152c33610b63565b6115735760405162461bcd60e51b815260206004820152601860248201527731b0b73737ba1032b9b1b0b8329032bc3834b930ba34b7b760411b6044820152606401610aa9565b61157d8383611b13565b9392505050565b6001600160a01b0381166000908152601b60205260408120548190156115cc576001600160a01b0383166000908152601b60205260409020546115c9906137c8612c8e565b90505b6115d583610b63565b156113c45750600092915050565b6115eb611810565b600b55565b6115f8611810565b6001600160a01b03821660009081526009602052604090205460ff16158061161e575080155b6116765760405162461bcd60e51b815260206004820152602360248201527f43616e6e6f74206578636c75646520616e2065786368616e67652066726f6d206044820152620e8c2f60eb1b6064820152608401610aa9565b6001600160a01b03919091166000908152601760205260409020805460ff1916911515919091179055565b6116a9611810565b600a805460ff1916911515919091179055565b6014546040805163585e42ef60e11b815290516000926001600160a01b03169163b0bc85de9160048083019260209291908290030181865afa158015611137573d6000803e3d6000fd5b61170e611810565b601691909155601555565b600654600090610100900460ff1615611749576003600f544361173c9190612d21565b101561174957506126ac90565b50600090565b611757611810565b6001600160a01b0381166117bc5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610aa9565b610b0981611ac3565b6019546001600160a01b031633146117ef5760405162461bcd60e51b8152600401610aa990612c28565b6001600160a01b03166000908152601c60205260409020805460ff19169055565b6000546001600160a01b031633146109395760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610aa9565b611872611810565b61187a611b8b565b42600e5543600f55565b6001600160a01b0383166118e65760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610aa9565b6001600160a01b0382166119475760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610aa9565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b601980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fed6cdfec6278ae5a354fde12b296022b0b257f5cb5843a4491932397ef649e4490600090a35050565b600654600090849060ff168015611a185750600654610100900460ff165b80611a3057506000546001600160a01b038281169116145b80611a4a57503360009081526007602052604090205460ff165b611a665760405162461bcd60e51b8152600401610aa990612bfb565b33611a72868286611ba4565b611a7d868686611c30565b50600195945050505050565b6000611a9d826001600160a01b0316611e61565b611aa957506000919050565b6113c46001600160a01b0383166380ac58cd60e01b611e94565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600654600090339060ff168015611b315750600654610100900460ff165b80611b4957506000546001600160a01b038281169116145b80611b6357503360009081526007602052604090205460ff165b611b7f5760405162461bcd60e51b8152600401610aa990612bfb565b33610abe818686611c30565b611b93611810565b6006805461ff001916610100179055565b6001600160a01b038381166000908152600260209081526040808320938616835292905220546000198114610fc45781811015611c235760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610aa9565b610fc48484848403611884565b6001600160a01b038316611c945760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610aa9565b6001600160a01b038216611cf65760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610aa9565b6001600160a01b03831660009081526008602052604090205460ff1615611d5f5760405162461bcd60e51b815260206004820152601e60248201527f61646472657373206973206e6f7420616c6c6f77656420746f2073656c6c00006044820152606401610aa9565b611d6a838383611eb0565b6000611d77848484611efb565b6001600160a01b03851660009081526001602052604090205490915082811015611df25760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610aa9565b6001600160a01b0380861660008181526001602052604080822087860390559287168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611e529087815260200190565b60405180910390a35050505050565b6000611e74826301ffc9a760e01b611f08565b80156113c45750611e8d826001600160e01b0319611f08565b1592915050565b6000611e9f83611e61565b801561157d575061157d8383611f08565b6001600160a01b0382166000908152601b60205260408120549003611eeb576001600160a01b0382166000908152601b602052604090204390555b611ef6838383611f91565b505050565b6000610d4384848461218d565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d91506000519050828015611f7a575060208210155b8015611f865750600081115b979650505050505050565b60145460408051630dd8715760e01b815290516000926001600160a01b031691630dd871579160048083019260209291908290030181865afa158015611fdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fff9190612c5f565b6120099042612d21565b600654909150610100900460ff16801561202c5750601454600160a01b900460ff165b801561205057506001600160a01b03831660009081526009602052604090205460ff165b801561206a575042601854603c6120679190612c8e565b11155b801561207857506015548110155b80156120a057506016546014546001600160a01b031660009081526001602052604090205410155b80156121205750601460009054906101000a90046001600160a01b03166001600160a01b031663d83067866040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061211e9190612d04565b155b1561218257426018556014546040805163e4fc6b6d60e01b815290516001600160a01b039092169163e4fc6b6d9160048082019260009290919082900301818387803b15801561216f57600080fd5b505af1925050508015612180575060015b505b610fc48484846123c2565b6001600160a01b038316600090815260176020526040812054829060ff161580156121d157506001600160a01b03841660009081526017602052604090205460ff16155b80156121e45750600654610100900460ff165b15612313576001600160a01b03851660009081526009602052604090205460ff16156122805760145460405163db017dc760e01b8152600481018590526001600160a01b039091169063db017dc7906024016020604051808303816000875af1158015612255573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122799190612c5f565b9050612313565b6001600160a01b03841660009081526009602052604090205460ff161561231357601454604051634fa26fd560e01b8152600481018590526001600160a01b0390911690634fa26fd5906024016020604051808303816000875af11580156122ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123109190612c5f565b90505b600061231f8285612d21565b905080156123ad576014546001600160a01b031660009081526001602052604090205461234d908290612c8e565b601480546001600160a01b03908116600090815260016020908152604091829020949094559154915184815291811692908916917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b6123b8868684612760565b9695505050505050565b600a5460ff1615806123e457503360009081526011602052604090205460ff16155b6124225760405162461bcd60e51b815260206004820152600f60248201526e1cdb9a5c195c881c995a9958dd1959608a1b6044820152606401610aa9565b600654610100900460ff16801561244757506000546001600160a01b03848116911614155b801561246c57506001600160a01b03831660009081526012602052604090205460ff16155b801561249157506001600160a01b03821660009081526012602052604090205460ff16155b15611ef657600d54156124f057600d545a11156124f05760405162461bcd60e51b815260206004820152601e60248201527f74686973206973206f76657220746865206d617820676173206c696d697400006044820152606401610aa9565b6000600c5411801561251b57506001600160a01b03821660009081526009602052604090205460ff16155b1561259a5761252861127b565b6001600160a01b03831660009081526001602052604090205461254c908390612c8e565b111561259a5760405162461bcd60e51b815260206004820181905260248201527f74686973206973206f76657220746865206d617820686f6c6420616d6f756e746044820152606401610aa9565b6000600b541180156125c457506001600160a01b03821660009081526009602052604090205460ff165b15612620576125d16113ca565b8111156126205760405162461bcd60e51b815260206004820181905260248201527f74686973206973206f76657220746865206d61782073656c6c20616d6f756e746044820152606401610aa9565b600a54610100900460ff1615611ef6576001600160a01b038216600090815260136020526040902054439003612687576001600160a01b0382166000908152601160205260408120805460ff19166001179055601080549161268183612d34565b91905055505b6001600160a01b0383166000908152601360205260409020544390036126de576001600160a01b0383166000908152601160205260408120805460ff1916600117905560108054916126d883612d34565b91905055505b6001600160a01b03821660009081526009602052604081205460ff161515900361271e576001600160a01b03821660009081526013602052604090204390555b6001600160a01b03831660009081526009602052604081205460ff1615159003611ef65750506001600160a01b03166000908152601360205260409020439055565b6006546000908290610100900460ff1680156127845750600a5462010000900460ff165b1561282e576000546001600160a01b038681169116148015906127ae575060006127ac611719565b115b80156127d357506001600160a01b03851660009081526012602052604090205460ff16155b80156127f857506001600160a01b03841660009081526012602052604090205460ff16155b1561282e57600061271061280a611719565b6128149086612ccb565b61281e9190612ce2565b905061282a8183612d21565b9150505b612839858583612842565b95945050505050565b6000826001600160a01b0316846001600160a01b0316036128a55760405162461bcd60e51b815260206004820152601f60248201527f796f752063616e6e6f74207472616e7366657220746f20796f757273656c66006044820152606401610aa9565b5092915050565b6000815180845260005b818110156128d2576020818501810151868301820152016128b6565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061157d60208301846128ac565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261292c57600080fd5b813567ffffffffffffffff8082111561294757612947612905565b604051601f8301601f19908116603f0116810190828211818310171561296f5761296f612905565b8160405283815286602085880101111561298857600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080604083850312156129bb57600080fd5b823567ffffffffffffffff8111156129d257600080fd5b6129de8582860161291b565b95602094909401359450505050565b80356001600160a01b0381168114612a0457600080fd5b919050565b60008060408385031215612a1c57600080fd5b612a25836129ed565b946020939093013593505050565b600060208284031215612a4557600080fd5b61157d826129ed565b600060208284031215612a6057600080fd5b5035919050565b600080600060608486031215612a7c57600080fd5b612a85846129ed565b9250612a93602085016129ed565b9150604084013590509250925092565b8015158114610b0957600080fd5b60008060408385031215612ac457600080fd5b612acd836129ed565b91506020830135612add81612aa3565b809150509250929050565b600060208284031215612afa57600080fd5b813561157d81612aa3565b60008060408385031215612b1857600080fd5b823567ffffffffffffffff811115612b2f57600080fd5b612b3b8582860161291b565b925050612b4a602084016129ed565b90509250929050565b60008060408385031215612b6657600080fd5b612b6f836129ed565b9150612b4a602084016129ed565b60008060408385031215612b9057600080fd5b50508035926020909101359150565b600181811c90821680612bb357607f821691505b602082108103612bd357634e487b7160e01b600052602260045260246000fd5b50919050565b604081526000612bec60408301856128ac565b90508260208301529392505050565b6020808252601390820152721d1c98591a5b99c81b9bdd08195b98589b1959606a1b604082015260600190565b6020808252601d908201527f63616c6c6572206973206e6f74207468652063656e7472616c2062726f000000604082015260600190565b600060208284031215612c7157600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156113c4576113c4612c78565b604081526000612cb460408301856128ac565b905060018060a01b03831660208301529392505050565b80820281158282048414176113c4576113c4612c78565b600082612cff57634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215612d1657600080fd5b815161157d81612aa3565b818103818111156113c4576113c4612c78565b600060018201612d4657612d46612c78565b506001019056fea26469706673582212205f0fe7ab24be5133a4a3270b14893519465468ad7745de0daa90049e1cec551064736f6c63430008130033

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

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